diff --git a/README-zh-CN.md b/README-zh-CN.md
new file mode 100644
index 000000000..63f9ed816
--- /dev/null
+++ b/README-zh-CN.md
@@ -0,0 +1,227 @@
+# gRPC Spring Boot Starter
+
+[![Build Status](https://travis-ci.org/yidongnan/grpc-spring-boot-starter.svg?branch=master)](https://travis-ci.org/yidongnan/grpc-spring-boot-starter)
+[![Maven Central with version prefix filter](https://img.shields.io/maven-central/v/net.devh/grpc-spring-boot-starter.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22net.devh%22%20grpc)
+[![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE)
+[![Crowdin](https://badges.crowdin.net/grpc-spring-boot-starter/localized.svg)](https://crowdin.com/project/grpc-spring-boot-starter)
+
+[![Client-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-client-spring-boot-autoconfigure.svg?label=Client-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-client-spring-boot-autoconfigure)
+[![Server-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-server-spring-boot-autoconfigure.svg?label=Server-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-server-spring-boot-autoconfigure)
+[![Common-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-common-spring-boot.svg?label=Common-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-common-spring-boot)
+
+README: [English](README.md) | [中文](README-zh-CN.md)
+
+**文档:** [English](https://yidongnan.github.io/grpc-spring-boot-starter/en/) | [中文](https://yidongnan.github.io/grpc-spring-boot-starter/zh-CN/)
+
+QQ交流群:294712648
+
+## 特性
+
+* 在 spring boot 应用中,通过 `@GrpcService` 自动配置并运行一个嵌入式的 gRPC 服务。
+
+* 使用 `@GrpcClient` 自动创建和管理您的 gRPC Channels 和 stubs
+
+* 支持[Spring Cloud](https://spring.io/projects/spring-cloud) (向 [Consul](https://github.com/spring-cloud/spring-cloud-consul) 或 [Eureka](https://github.com/spring-cloud/spring-cloud-netflix) 或 [Nacos](https://github.com/spring-cloud-incubator/spring-cloud-alibaba) 注册服务并获取 gRPC 服务端信息)
+
+* 支持[Spring Sleuth](https://github.com/spring-cloud/spring-cloud-sleuth)作为分布式链路跟踪解决方案(如果[brave-instrument-grpc](https://mvnrepository.com/artifact/io.zipkin.brave/brave-instrumentation-grpc)存在)
+
+* 支持全局和自定义的 gRPC 服务端/客户端拦截器
+
+* 支持 [Spring-Security](https://github.com/spring-projects/spring-security)
+
+* 支持metric (基于[micrometer](https://micrometer.io/)/[actuator](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-actuator) )
+
+* 也适用于 (non-shaded) grpc-netty
+
+## 版本
+
+2.x.x.RELEASE 支持 Spring Boot 2.1.x/2.2.x 和 Spring Cloud Greenwich / Hoxton。
+
+最新版本: `2.5.1.RELEASE`
+
+( `2.4.0.RELEASE` 用于 Spring Boot 2.0.x & Spring Cloud Finchy).
+
+1.x.x.RELEASE 支持 Spring Boot 1 & Spring Cloud Edgware, Dalston, Camden.
+
+最新版本: `1.4.2.RELEASE`
+
+**注意:** 该项目也可以在没有 Spring-Boot 的情况下使用,但是您需要手动配置一些 bean。
+
+## 用法
+
+### gRPC 服务端 + 客户端
+
+使用一下命令添加 Maven 依赖项:
+
+````xml
+
+ net.devh
+ grpc-spring-boot-starter
+ 2.5.1.RELEASE
+
+````
+
+Gradle:
+
+````gradle
+dependencies {
+ compile 'net.devh:grpc-spring-boot-starter:2.5.1.RELEASE'
+}
+````
+
+### gRPC 服务端
+
+使用一下命令添加 Maven 依赖项:
+
+````xml
+
+ net.devh
+ grpc-server-spring-boot-starter
+ 2.5.1.RELEASE
+
+````
+
+Gradle:
+
+````gradle
+dependencies {
+ compile 'net.devh:grpc-server-spring-boot-starter:2.5.1.RELEASE'
+}
+````
+
+在服务端接口实现类上添加 `@GrpcService` 注解。
+
+````java
+@GrpcService
+public class GrpcServerService extends GreeterGrpc.GreeterImplBase {
+
+ @Override
+ public void sayHello(HelloRequest req, StreamObserver responseObserver) {
+ HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+
+}
+````
+
+默认情况下,Grpc 服务器将监听端口 `9090`。 端口的配置和其他的 [设置](grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/config/GrpcServerProperties.java) 可以通过 Spring 的属性机制进行更改。 服务端的配置使用 `grpc.server.` 前缀。
+
+详情请参阅我们的[文档](https://yidongnan.github.io/grpc-spring-boot-starter/)。
+
+### gRPC 客户端
+
+使用一下命令添加 Maven 依赖项:
+
+````xml
+
+ net.devh
+ grpc-client-spring-boot-starter
+ 2.5.1.RELEASE
+
+````
+
+Gradle:
+
+````gradle
+dependencies {
+ compile 'net.devh:grpc-client-spring-boot-starter:2.5.1.RELEASE'
+}
+````
+在 grpc 客户端的的 stub 字段上添加 `@GrpcClient(serverName)` 注解。
+
+* 请不要将 @GrpcClient 与 `@Autowireed` 或 `@Inject` 一起使用。
+
+ ````java
+ @GrpcClient("gRPC server name")
+ private GreeterGrpc.GreeterBlockingStub greeterStub;
+ ````
+
+**注意:** 你可以将相同的 grpc 服务端名称用于多个 channel, 也可以使用不同的 stub (甚至使用不同的 stub 拦截器)
+
+然后您可以向您的服务器发送查询,就像这样:
+
+````java
+HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName(name).build());
+````
+
+可以单独配置每个客户端的目标地址。 但在某些情况下,您可以仅依靠默认配置。 您可以通过 `NameResolver.Factory` Bean 类自定义默认的 url 映射。 如果您没有配置那个Bean,那么默认的 uri 将使用默认方案和名称(如:`dns:`):
+
+这些配置和其他的 [设置](grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java) 可以通过 Spring 的属性机制进行更改。 客户端使用`grpc.client.(serverName)。` 前缀。
+
+详情请参阅我们的[文档](https://yidongnan.github.io/grpc-spring-boot-starter/)。
+
+## 使用 (non-shaded) grpc-netty 运行
+
+这个库支持`grpc-netty`和`grpc-nety-shaded`。 后一种可能会防止与不兼容的 gRPC 版本冲突或不同 netty 版本之间的冲突。
+
+**注意:** 如果在classpath 中存在 shaded netty, 则 shaded netty 将使用有线与 non-shaded grpc-netty。
+
+您可以在 Maven 中这样使用。
+
+````xml
+
+ io.grpc
+ grpc-netty
+ ${grpcVersion}
+
+
+
+
+ net.devh
+ grpc-spring-boot-starter
+ ...
+
+
+ io.grpc
+ grpc-netty-shaded
+
+
+
+
+
+ net.devh
+ grpc-server-spring-boot-starter
+ ...
+
+
+ io.grpc
+ grpc-netty-shaded
+
+
+
+
+
+ net.devh
+ grpc-client-spring-boot-starter
+ ...
+
+
+ io.grpc
+ grpc-netty-shaded
+
+
+
+````
+
+Gradle:
+
+````groovy
+compile "io.grpc:grpc-netty:${grpcVersion}"
+
+compile 'net.devh:grpc-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For both
+compile 'net.devh:grpc-client-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the client (only)
+compile 'net.devh:grpc-server-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the server (only)
+````
+
+## 示例项目
+
+在 [这里](examples)可以阅读更多关于我们的示例项目。
+
+## 排除故障
+
+请参阅我们的[文档](https://yidongnan.github.io/grpc-spring-boot-starter/en/trouble-shooting)寻求帮助。
+
+## 参与贡献
+
+我们始终欢迎您对项目作出任何贡献。 详见[CONTRIBUTING.md](CONTRIBUTING.md)。
diff --git a/README-zh.md b/README-zh.md
deleted file mode 100644
index e85ef37bf..000000000
--- a/README-zh.md
+++ /dev/null
@@ -1,554 +0,0 @@
-# gRPC Spring Boot Starter
-
-[![Build Status](https://travis-ci.org/yidongnan/grpc-spring-boot-starter.svg?branch=master)](https://travis-ci.org/yidongnan/grpc-spring-boot-starter)
-[![Maven Central with version prefix filter](https://img.shields.io/maven-central/v/net.devh/grpc-spring-boot-starter.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22net.devh%22%20grpc)
-[![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE)
-
-[![Client-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-client-spring-boot-autoconfigure.svg?label=Client-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-client-spring-boot-autoconfigure)
-[![Server-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-server-spring-boot-autoconfigure.svg?label=Server-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-server-spring-boot-autoconfigure)
-[![Common-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-common-spring-boot.svg?label=Common-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-common-spring-boot)
-
-README: [English](README.md) | [中文](README-zh.md)
-
-**GitHub地址:https://github.com/yidongnan/grpc-spring-boot-starter**
-
-Java技术交流群:294712648
-
-## 特点
-
-* 使用`@ GrpcService`自动创建并运行一个 gRPC 服务,内嵌在 spring-boot 应用中
-
-* 使用`@ GrpcClient`自动创建和管理你的``channel``和``stub``
-
-* 支持 [Spring Cloud](https://spring.io/projects/spring-cloud)(向 [Consul](https://github.com/spring-cloud/spring-cloud-consul) 或 [Eureka](https://github.com/spring-cloud/spring-cloud-netflix) 或 [Nacos](https://github.com/spring-cloud-incubator/spring-cloud-alibaba) 注册服务并获取gRPC服务信息)
-
-* 支持 [Spring Sleuth](https://github.com/spring-cloud/spring-cloud-sleuth) 进行链路跟踪(需要单独引入 [brave-instrumentation-grpc](https://mvnrepository.com/artifact/io.zipkin.brave/brave-instrumentation-grpc))
-
-* 支持对 server、client 分别设置全局拦截器或单个的拦截器
-
-* 支持 [Spring-Security](https://github.com/spring-projects/spring-security)
-
-* 支持 metric ([micrometer](https://micrometer.io/) / [actuator](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-actuator))
-
-* 可以使用 (non-shaded) grpc-netty
-
-## 版本
-
-2.x.x.RELEASE 支持 Spring Boot 2.1+ & Spring Cloud Greenwich。
-
-最新的版本:``2.5.1.RELEASE``
-
-(使用 `2.4.0.RELEASE` 版本可以支持 Spring Boot 2.0.X & Spring Cloud Finchley).
-
-1.x.x.RELEASE 支持 Spring Boot 1 & Spring Cloud Edgware 、Dalston、Camden。
-
-最新的版本:``1.4.2.RELEASE``
-
-**注意:** 此项目也可以在没有 Spring-Boot 的场景下使用,但需要手动的配置相关的 bean。
-
-## 使用方式
-
-### gRPC server + client
-
-如果使用的是 Maven,添加如下依赖
-
-````xml
-
- net.devh
- grpc-spring-boot-starter
- 2.5.1.RELEASE
-
-````
-
-如果使用的 Gradle,添加如下依赖
-
-````gradle
-dependencies {
- compile 'net.devh:grpc-spring-boot-starter:2.5.1.RELEASE'
-}
-````
-
-### gRPC 服务端
-
-如果使用的是 Maven,添加如下依赖
-
-````xml
-
- net.devh
- grpc-server-spring-boot-starter
- 2.5.1.RELEASE
-
-````
-
-如果使用的 Gradle,添加如下依赖
-
-````gradle
-dependencies {
- compile 'net.devh:grpc-server-spring-boot-starter:2.5.1.RELEASE'
-}
-````
-
-实现 gRPC server 的业务逻辑,并使用 ``@GrpcService`` 注解
-
-````java
-@GrpcService
-public class GrpcServerService extends GreeterGrpc.GreeterImplBase {
-
- @Override
- public void sayHello(HelloRequest req, StreamObserver responseObserver) {
- HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
- responseObserver.onNext(reply);
- responseObserver.onCompleted();
- }
-}
-````
-
-设置 gRPC 的 host 跟 port ,默认的监听的 port 是 9090。其他配置属性可以参考
-[settings](grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/config/GrpcServerProperties.java)。
-所有的配置属性在 server 中使用需增加 `grpc.server.` 的前缀
-
-#### 服务端配置属性示例
-
-````properties
-grpc.server.port=9090
-grpc.server.address=0.0.0.0
-#grpc.server.inProcessName=test
-````
-
-#### 对 Server 进行自定义
-
-当前项目同样支持对 `ServerBuilder` 的自定义修改,需要在创建的过程中使用 `GrpcServerConfigurer` beans。
-
-````java
-@Bean
-public GrpcServerConfigurer keepAliveServerConfigurer() {
- return serverBuilder -> {
- if (serverBuilder instanceof NettyServerBuilder) {
- ((NettyServerBuilder) serverBuilder)
- .keepAliveTime(30, TimeUnit.SECONDS)
- .keepAliveTimeout(5, TimeUnit.SECONDS)
- .permitKeepAliveWithoutCalls(true);
- }
- };
-}
-````
-
-#### Server-Security
-支持使用 Spring-Security 加密你的 gRPC 应用。你只需要添加 Spring-Security(core 或者 config)依赖,然后根据需要再增加加密的配置
-
-##### 首先需要选择一个认证方案
-
-
-* **BasicAuth(基础认证)**
-
- ````java
- @Bean
- AuthenticationManager authenticationManager() {
- final List providers = new ArrayList<>();
- providers.add(...); // Possibly DaoAuthenticationProvider
- return new ProviderManager(providers);
- }
-
- @Bean
- GrpcAuthenticationReader authenticationReader() {
- final List readers = new ArrayList<>();
- readers.add(new BasicGrpcAuthenticationReader());
- return new CompositeGrpcAuthenticationReader(readers);
- }
- ````
-
-* **Bearer Authentication (OAuth2/OpenID-Connect)**
-
- ````java
- @Bean
- AuthenticationManager authenticationManager() {
- final List providers = new ArrayList<>();
- providers.add(...); // Possibly JwtAuthenticationProvider
- return new ProviderManager(providers);
- }
-
- @Bean
- GrpcAuthenticationReader authenticationReader() {
- final List readers = new ArrayList<>();
- readers.add(new BearerAuthenticationReader(accessToken -> new BearerTokenAuthenticationToken(accessToken)));
- return new CompositeGrpcAuthenticationReader(readers);
- }
- ````
-
- 你可能还想定义自己的 *GrantedAuthoritiesConverter* ,将权限和角色的信息映射到 Spring Security 的 `GrantedAuthority` 中
-
-* **Certificate Authentication(证书认证)**
-
- ````java
- @Bean
- AuthenticationManager authenticationManager() {
- final List providers = new ArrayList<>();
- providers.add(new X509CertificateAuthenticationProvider(userDetailsService()));
- return new ProviderManager(providers);
- }
-
- @Bean
- GrpcAuthenticationReader authenticationReader() {
- final List readers = new ArrayList<>();
- readers.add(new SSLContextGrpcAuthenticationReader());
- return new CompositeGrpcAuthenticationReader(readers);
- }
- ````
-
- 相关的配置属性如下:
-
- ````properties
- grpc.server.security.enabled=true
- grpc.server.security.certificateChain=file:certificates/server.crt
- grpc.server.security.privateKey=file:certificates/server.key
- grpc.server.security.trustCertCollection=file:certificates/trusted-clients-collection
- grpc.server.security.clientAuth=REQUIRE
- ````
-
-* **使用 `CompositeGrpcAuthenticationReader` 类链式的调用多个认证方案**
-* **自定义认证方式(继承并实现 `GrpcAuthenticationReader` 类)**
-
-##### 如何去保护你的这些服务
-
-* **使用 Spring-Security 的注解**
-
- ````java
- @Configuration
- @EnableGlobalMethodSecurity(proxyTargetClass = true, ...)
- public class SecurityConfiguration {
- ````
-
- 如果你想使用 Spring Security 相关的注解的话,`proxyTargetClass` 属性是必须的!
- 但是你会受到一条警告,提示 MyServiceImpl#bindService() 方式是用 final 进行修饰的。
- 这条警告目前无法避免,但它是安全的,可以忽略它。
-
-* **手动配置**
-
- ````java
- @Bean
- AccessDecisionManager accessDecisionManager() {
- final List> voters = new ArrayList<>();
- voters.add(new AccessPredicateVoter());
- return new UnanimousBased(voters);
- }
-
- @Bean
- GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
- final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
- source.set(MyServiceGrpc.getSecureMethod(), AccessPredicate.hasRole("ROLE_USER"));
- source.setDefault(AccessPredicate.permitAll());
- return source;
- }
- ````
-
-### gRPC 客户端
-
-如果使用的是 Maven,添加如下依赖
-
-````xml
-
- net.devh
- grpc-client-spring-boot-starter
- 2.5.1.RELEASE
-
-````
-
-如果使用的 Gradle,添加如下依赖
-
-````gradle
-dependencies {
- compile 'net.devh:grpc-client-spring-boot-starter:2.5.1.RELEASE'
-}
-````
-
-这里有三种方式去或得一个gRPC server的连接
-
-
-* 使用 `grpcChannelFactory.createChannel(serverName)` 去创建一个 `Channel`,并创建一个自己的 gRPC stub.
-
- ````java
- @Autowired
- private GrpcChannelFactory grpcChannelFactory;
-
- private GreeterGrpc.GreeterBlockingStub greeterStub;
-
- @PostConstruct
- public void init() {
- Channel channel = grpcChannelFactory.createChannel("gRPC server name");
- greeterStub = GreeterGrpc.newBlockingStub(channel);
- }
- ````
-
-* 通过在 `Channel` 类型的字段上加入 `@GrpcClient(serverName)` 注解,并创建一个自己的 gRPC stub.
- * 不需要使用 `@Autowired` 或者 `@Inject` 来进行注入
-
- ````java
- @GrpcClient("gRPC server name")
- private Channel channel;
-
- private GreeterGrpc.GreeterBlockingStub greeterStub;
-
- @PostConstruct
- public void init() {
- greeterStub = GreeterGrpc.newBlockingStub(channel);
- }
- ````
-
-* 直接将 `@GrpcClient(serverName)` 注解加在调用客户端的 stub 上
- * 不需要使用 `@Autowired` 或者 `@Inject` 来进行注入
-
- ````java
- @GrpcClient("gRPC server name")
- private GreeterGrpc.GreeterBlockingStub greeterStub;
- ````
-
-**注意:** 你可以为多个 channels 和多个不同的 stubs 使用相同的 serverName (除非他们拦截器不一样).
-
-然后你可以直接向服务端发起请求,如下:
-
-````java
-HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName(name).build());
-````
-
-可以单独为每一个 client 配置对应的 address
-但在某些情况下,你可以调整默认的配置。
-你可以通过 `NameResolver.Factory` beans 去自定义默认的 url 映射,如果你没有配置这个 bean,那将会按照下面的方式进行解析:
-
-* 如果存在一个 `DiscoveryClient` 的 bean,这时会使用 client name 去注册中心上进行获取对应服务的 address
-* 否则 client 端将使用 `localhost` 和 `9090` 端口
-
-其他的配置属性参考 [settings](grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java),所有的配置文件在 client 端使用时需要增加 `grpc.client.(serverName).`的前缀
-
-你也可以配置多个目标地址,请求时会自动使用负载均衡
-
-* `static://127.0.0.1:9090,[::1]:9090`
-
-你也可以使用服务发现去获取目标地址(要求一个 `DiscoveryClient` bean)
-
-* `discovery:///my-service-name`
-
-此外,你也可以使用 DNS 的方式去获取目标地址
-
-* `dns:///example.com`
-
-同时,你也可以使用如下方式直接进程内访问
-
-* `in-process:test`
-
-它会通过DNS将域名解析出所有真实的 IP 地址,通过使用这些真实的IP地址去做负载均衡。
-需要注意的是 `grpc-java` 出于性能的考虑对 DNS 返回的结果做缓存。
-有关这些和其他原生支持的 `NameResolverProviders` 参考官方文档 [grpc-java sources](https://github.com/grpc/grpc-java)
-
-#### 客户端配置属性示例
-
-````properties
-grpc.client.GLOBAL.enableKeepAlive=true
-
-grpc.client.(gRPC server name).address=static://localhost:9090
-# Or
-grpc.client.myName.address=static://localhost:9090
-````
-
-`GLOBAL` 是一个特殊的常量,它可以用于对所有 Client 统一的设置属性。
-属性覆盖的顺序:Client单独的属性 > `GLOBAL`的属性 > 默认的属性
-
-#### 自定义 Client
-
-This library also supports custom changes to the `ManagedChannelBuilder` and gRPC client stubs during creation by creating `GrpcChannelConfigurer` and `StubTransformer` beans.
-当前项目支持对 `ManagedChannelBuilder` 的自定义,在 gRPC client stub创建的过程中,通过使用 `GrpcChannelConfigurer` 或 `StubTransformer` bean
-来完成自定义操作
-
-````java
-@Bean
-public GrpcChannelConfigurer keepAliveClientConfigurer() {
- return (channelBuilder, name) -> {
- if (channelBuilder instanceof NettyChannelBuilder) {
- ((NettyChannelBuilder) channelBuilder)
- .keepAliveTime(15, TimeUnit.SECONDS)
- .keepAliveTimeout(5, TimeUnit.SECONDS);
- }
- };
-}
-
-@Bean
-public StubTransformer authenticationStubTransformer() {
- return (clientName, stub) -> stub.withCallCredentials(grpcCredentials(clientName));
-}
-````
-
-#### 客户端认证
-
-**注意:** 以下列出的一些方法仅仅适用于通过注入得到的 stubs,如果你通过注入 Channel,手动的在去创建 stubs,这就需要你自己手动的
-去配置凭证。然而你同样能从目前所提供的一些辅助类方法中收益。
-
-客户端有许多不同的认证方式,我们只需定义一个类型为 `CallCredentials` 的 bean,它会自动作用于身份验证。目前通过一些辅助方法可以支持
-下列的认证方式:
-
-* **BasicAuth**
-
- ````java
- @Bean
- CallCredentials grpcCredentials() {
- return CallCredentialsHelper.basicAuth(username, password);
- }
- ````
-
-* **Bearer Authentication (OAuth2, OpenID-Connect)**
-
- ````java
- @Bean
- CallCredentials grpcCredentials() {
- return CallCredentialsHelper.bearerAuth(token);
- }
- ````
-
-* **Certificate Authentication**
-
- 需要一些配置属性:
-
- ````properties
- #grpc.client.test.security.authorityOverride=localhost
- #grpc.client.test.security.trustCertCollection=file:certificates/trusted-servers-collection
- grpc.client.test.security.clientAuthEnabled=true
- grpc.client.test.security.certificateChain=file:certificates/client.crt
- grpc.client.test.security.privateKey=file:certificates/client.key
-
-* **为每个 client 使用不同的认证**
-
- 通过定义一个 `StubTransformer` bean 来代替原有的 `CallCredentials` bean
-
- ````java
- @Bean
- StubTransformer grpcCredentialsStubTransformer() {
- return CallCredentialsHelper.mappedCredentialsStubTransformer(
- Map.of(
- clientA, callCredentialsAC,
- clientB, callCredentialsB,
- clientC, callCredentialsAC));
- }
- ````
-
- **注意:** 如果你配置了 `CallCredentials` bean,然后再使用 `StubTransformer` 的话可能会造成冲突。
-
-## 使用 (non-shaded)grpc-netty
-
-当前项目目前支持 `grpc-netty` 和 `grpc-netty-shaded`。
-使用 `grpc-netty-shaded` 可以防止 grpc 跟 netty 版本的兼容性问题。
-
-**注意:** 如果 `grpc-netty-shaded` 已经存在于 classpath 中, 那么将优先使用 shaded-netty
-
-如果你使用的Maven,你可以使用如下的配置:
-
-````xml
-
- io.grpc
- grpc-netty
- ${grpcVersion}
-
-
-
-
- net.devh
- grpc-spring-boot-starter
- ...
-
-
- io.grpc
- grpc-netty-shaded
-
-
-
-
-
- net.devh
- grpc-server-spring-boot-starter
- ...
-
-
- io.grpc
- grpc-netty-shaded
-
-
-
-
-
- net.devh
- grpc-client-spring-boot-starter
- ...
-
-
- io.grpc
- grpc-netty-shaded
-
-
-
-````
-
-如果你使用的 Gradle,你可以使用如下的配置:
-
-````groovy
-compile "io.grpc:grpc-netty:${grpcVersion}"
-
-compile 'net.devh:grpc-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For both
-compile 'net.devh:grpc-client-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the client (only)
-compile 'net.devh:grpc-server-spring-boot-starter:...' exclude group: 'io.grpc', module: 'grpc-netty-shaded' // For the server (only)
-````
-
-## 示例项目
-
-查看更多的示例项目 [here](examples).
-
-## 常见的问题
-
-在你深入去查问题之前,请先确保 grpc 跟 netty 的版本是彼此兼容的。
-当前项目自带的依赖会确保 grpc 和 netty 是能一起正常工作。
-但是在某些情况下,你可能需要用到其他库(如 tcnative )或其他依赖项需要用到不同的 netty 版本,这就可能会造成版本冲突。
-为了防止此类问题,gRPC 和 我们建议你使用 grpc-netty-shaded 依赖。
-如果你使用 (non-shaded) grpc-netty,请查看[表格](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty)中展示的[grpc-java](https://github.com/grpc/grpc-java) 的兼容版本
-
-### SSL 相关的问题
-
-* `java.lang.IllegalStateException: Failed to load ApplicationContext`
-* `Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'grpcServerLifecycle'`
-* `Caused by: java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available`
-
-or
-
-* `AbstractMethodError: io.netty.internal.tcnative.SSL.readFromSSL()`
-
-or
-
-* `javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem`
-
-您的类路径中没有 `netty-tcnative ...`库或者没有正确的版本。
-
-(在netty 4.1.24.Final -> 4.1.24.Final 和 netty-tcnative 2.0.8.Final -> 2.0.12.Final 版本之间存在非向下兼容更新)
-
-查看 [grpc-java: Security](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty).
-
-### 测试期间 SSL 的问题
-
-默认情况下,gRPC 客户端假定服务器使用的 TLS,并尝试使用安全连接,在开发和测试期间,一般都不需要证书,你可以切换到 `PLAINTEXT` 的连接方式。
-
-````properties
-grpc.client.(gRPC server name).negotiationType=PLAINTEXT
-````
-
-**注意:** 在生产环境,我们强烈推荐你使用 `TLS` 的模式。
-
-### 在测试模式下,端口已经被使用
-
-有时候你只想启动你的应用程序去检测服务之间的交互,那么这将启动 gRPC 服务,然后你不需要为每个测试方法或测试类单独的去关闭 gRPC 服务,
-在你的测试类或者方法中使用 `@DirtiesContext` 注解可以避免这个问题。
-
-### 找不到与 xxx 匹配的名称
-
-* `io.grpc.StatusRuntimeException: UNAVAILABLE: io exception`
-* `Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem`
-* `Caused by: java.security.cert.CertificateException: No name matching gRPC server name found`
-
-客户端配置的 `gRPC server name` 的名称与服务器上公用或者备用的证书名称不匹配。你必须将 `grpc.client.(gRPC server name).security.authorityOverride` 属性设置成一个存在的名称。
-
-## 贡献
-
-我们欢迎任何人为这个项目做出自己的贡献! 贡献时需要参考 [CONTRIBUTING.md](CONTRIBUTING.md) 文档.
diff --git a/README.md b/README.md
index 2b4a83f6b..6d8b41b4b 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,15 @@
[![Build Status](https://travis-ci.org/yidongnan/grpc-spring-boot-starter.svg?branch=master)](https://travis-ci.org/yidongnan/grpc-spring-boot-starter)
[![Maven Central with version prefix filter](https://img.shields.io/maven-central/v/net.devh/grpc-spring-boot-starter.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22net.devh%22%20grpc)
[![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE)
+[![Crowdin](https://badges.crowdin.net/grpc-spring-boot-starter/localized.svg)](https://crowdin.com/project/grpc-spring-boot-starter)
[![Client-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-client-spring-boot-autoconfigure.svg?label=Client-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-client-spring-boot-autoconfigure)
[![Server-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-server-spring-boot-autoconfigure.svg?label=Server-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-server-spring-boot-autoconfigure)
[![Common-Javadoc](https://www.javadoc.io/badge/net.devh/grpc-common-spring-boot.svg?label=Common-Javadoc)](https://www.javadoc.io/doc/net.devh/grpc-common-spring-boot)
-README: [English](README.md) | [中文](README-zh.md)
+README: [English](README.md) | [中文](README-zh-CN.md)
-**Documentation:** [English](https://yidongnan.github.io/grpc-spring-boot-starter/en/)
+**Documentation:** [English](https://yidongnan.github.io/grpc-spring-boot-starter/en/) | [中文](https://yidongnan.github.io/grpc-spring-boot-starter/zh-CN/)
## Features
diff --git a/docs/index.md b/docs/index.md
index e1a646f15..4647ac8b6 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -3,3 +3,4 @@
Please select a language:
- [English](en)
+- [中文](zh-CN)
diff --git a/docs/zh-CN/actuator.md b/docs/zh-CN/actuator.md
new file mode 100644
index 000000000..69c1e5dcc
--- /dev/null
+++ b/docs/zh-CN/actuator.md
@@ -0,0 +1,145 @@
+# 支持 Spring Boot Actuator
+
+[<- 返回索引](index)
+
+此页面重点介绍与 [Spring-Boot-Actator](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html) 的集成。 这是一个可选的功能。 支持的特性
+
+- 客户端 + 服务端指标
+- 服务端的`InfoContributor`
+
+## 目录
+
+- [依赖项](#dependencies)
+- [指标](#metrics)
+ - [计数器](#counter)
+ - [计时器](#timer)
+ - [查看指标](#viewing-the-metrics)
+ - [指标配置](#metric-configuration)
+- [InfoContributor](#infocontributor)
+- [关闭指标功能](#opt-out)
+
+## 依赖项
+
+指标收集和其他执行器一样都是可选的,如果应用程序环境中有 `MeterRegistry` ,它们将自动启用。
+
+您可以简单地通过向Maven添加以下依赖来实现这一点:
+
+````xml
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+````
+
+Gradle:
+
+````groovy
+compile("org.springframework.boot:spring-boot-starter-actuator")
+````
+
+> **注意:** 在大多数情况下,您还需要 `spring-boot-web` 依赖才能实际查看到指标。 请注意,spring-boot-web 运行的端口于不同的 grpc 服务端 (通常是 `8080`)。 如果您不想添加添加一个 web-server,您仍然可以通过 JMX (如果启用的话) 访问这些指标。
+
+## 指标
+
+一旦依赖关系被添加,grpc-spring-boot-starter 将自动配置`ClientIntercertor` / `ServerInterceptor` 以收集指标。
+
+### 计数器
+
+- `grpc.client.requests.sent`: 发送的总请求数。
+- `grpc.client.responses.received`: 接受的总响应数。
+- `grpc.server.requests.received`: 收到的总请求数。
+- `grpc.server.responses.sent`: 发送的总响应数。
+
+**标签**
+
+- `service`: 请求的 grpc 服务名称(使用 protubuf 名称)
+- `method`: 请求的 grpc 方法名称(使用 protobuf 名称)
+- `methodType`: 请求的 grpc 方法的类型。
+
+### 计时器
+
+- `grpc.client.processing.duration`: 客户端完成请求所花费的总时间,包括网络延迟。
+- `grpc.server.processing.duration`: 服务端完成请求所花费的时间。
+
+**标签**
+
+- `service`: 请求的 grpc 服务名称(使用 protobuf 名称)
+- `method`: 请求的 grpc 方法名称(使用 protobuf 名称)
+- `methodType`: 请求的 grpc 方法的类型。
+- `statusCode`: 响应的 `Status.Code`
+
+### 查看指标
+
+您可以在 `/actorator/metrics` (需要一个web-server) 或通过 JMX 查看 grpc 的指标以及其他指标。
+
+> **注意:** 你可能需要先启用指标。
+>
+> ````properties management.endpoints.web.exposure.include=metrics
+>
+> # management.endpoints.jmx.exposure.include=metrics
+>
+> management.endpoint.metrics.enabled=true ````
+
+阅读官方文档以了解更多关于[Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html) 的信息。
+
+### 指标配置
+
+默认情况下,客户端只会为已进行的请求创建指标。 然而,服务端将尝试所有找到并注册的服务,来初始化它们的指标。
+
+您可以通过覆盖Bean的创建自定义的行为。 下面使用`MetricCollectingClientInterceptor`来展示这一点:
+
+````java
+@Bean
+MetricCollectingClientInterceptor metricCollectingClientInterceptor(MeterRegistry registry) {
+ MetricCollectingClientInterceptor collector = new MetricCollectingClientInterceptor(registry,
+ counter -> counter.tag("app", "myApp"), // Customize the Counters
+ timer -> timer.tag("app", "myApp"), // Customize the Timers
+ Code.OK, Code.INVALID_ARGUMENT, Code.UNAUTHENTICATED); // Eagerly initialized status codes
+ // Pre-generate metrics for some services (to avoid missing metrics after restarts)
+ collector.preregisterService(MyServiceGrpc.getServiceDescriptor());
+ return collector;
+}
+````
+
+## InfoContributor
+
+*仅限服务器*
+
+服务端会自动配置一个 [`InfoContributor`](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/actuate/info/InfoContributor.html) 并公开一下信息:
+
+- `grpc.server`:
+ - `port`: grpc 服务端的端口
+ - `services`: grpc 的服务列表
+ - 方法
+
+您可以在 `/actorator/info` (需要一个web-server) 或通过 JMX 查看 grpc 的信息以及其他信息。
+
+> **注意:** 你可能需要先启用信息。
+>
+> ````properties management.endpoints.web.exposure.include=info
+>
+> # management.endpoints.jmx.exposure.include=info
+>
+> management.endpoint.info.enabled=true ````
+
+您可以使用 `grpc.server.reflectionServiceEnabled=false` 来打开服务列表(对于 actuator 和 grpc)。
+
+## 关闭指标功能
+
+您可以选择退出自动配置,使用以下注解:
+
+````java
+@EnableAutoConfiguration(exclude = {GrpcClientMetricAutoConfiguration.class, GrpcServerMetricAutoConfiguration.class})
+````
+
+或使用配置:
+
+````properties
+spring.autoconfigure.exclude=\
+net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration,\
+net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration
+````
+
+----------
+
+[<- 返回索引](index)
diff --git a/docs/zh-CN/benchmarking.md b/docs/zh-CN/benchmarking.md
new file mode 100644
index 000000000..77dcf1fd7
--- /dev/null
+++ b/docs/zh-CN/benchmarking.md
@@ -0,0 +1,22 @@
+# 基准测试
+
+[<- 返回索引](index)
+
+这个项目不会给 gRPC-java 增加任何性能开销。
+
+请参考官方的 gRPC 基准测试:
+
+- [grpc.io: Benchmarking](https://grpc.io/docs/guides/benchmarking/)
+- [grpc-java: Running Benchmarks](https://github.com/grpc/grpc-java/tree/master/benchmarks#grpc-benchmarks)
+
+与纯 HTTP 相比,gRPC 具有很多优势,但是很难将它数字化。 经过高度优化的 Web 服务器的性能与普通的 gRPC 服务器可能一样好。
+
+下面是普通HTTP与 grpc 的主要优点/差异:
+
+- 二进制数据格式 (更快, 但不可读)
+- Protobuf 定义的数据结构,可以用于为许多语言生成数据类和客户端。
+- HTTP/2 连接和连接池
+
+----------
+
+[<- 返回索引](index)
diff --git a/docs/zh-CN/brave.md b/docs/zh-CN/brave.md
new file mode 100644
index 000000000..de0d47b59
--- /dev/null
+++ b/docs/zh-CN/brave.md
@@ -0,0 +1,72 @@
+# 支持 Brave / Sleuth
+
+[<- 返回索引](index)
+
+此页面将着重介绍与 [Brave](https://github.com/openzipkin/brave) / [Sleuth](https://spring.io/projects/spring-cloud-sleuth) 的集成。 这是一个可选的功能。
+
+## 目录
+
+- [依赖项](#dependencies)
+ - [Brave](#brave)
+ - [Spring Cloud Sleuth](#spring-cloud-sleuth)
+- [关闭链路跟踪](#opt-out)
+- [附加信息](#additional-notes)
+
+## 依赖项
+
+grpc-spring-boot-starter 支持为 `Brave Instrumentation:GRPC` 提供自动配置。 然而,有两个要求:
+
+1. 您需要在 classpath 添加 Brave 依赖项。
+2. 您需要在应用上下文中有一个 `Trace` bean。 *如果您的 classpath 有 Spring Cloud Sleuth,它将自动为您配置此 Bean*
+
+### Brave
+
+您可以在 Maven 中添加 Brave 的依赖项。
+
+````xml
+
+ io.zipkin.brave
+ brave-instrumentation-grpc
+
+````
+
+Gradle:
+
+````groovy
+compile("io.zipkin.brave:brave-instrumentation-grpc")
+````
+
+### Spring Cloud Sleuth
+
+您可以在 Maven 中添加 Sleuth 依赖
+
+````xml
+
+ org.springframework.cloud
+ spring-cloud-starter-sleuth
+
+````
+
+Gradle:
+
+````groovy
+compile("org.springframework.cloud:spring-cloud-starter-sleuth")
+````
+
+请参阅[官方文件](https://spring.io/projects/spring-cloud-sleuth)以了解如何设置 / 配置 Sleuth。
+
+## 关闭链路跟踪
+
+您可以使用以下属性关闭 grpc 的链路跟踪:
+
+````property
+spring.sleuth.grpc.enabled=false
+````
+
+## 附加信息
+
+Spring-Cloud-Sleuth 提供了一些类,例如[`SpringAwareManagedChannelBuilder`](https://javadoc.io/page/org.springframework.cloud/spring-cloud-sleuth-core/latest/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.html),这些类仅仅由于与其他的库兼容而存在。 不要跟那个项目一期使用。 grpc-spring-boot-starter 通过 [`GrpcChannelFactory`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/channelfactory/GrpcChannelFactory.html) 和相关类提供相同 / 扩展的功能提供了开箱即用的能力。 相关阅读 [sleuth's javadoc note](https://github.com/spring-cloud/spring-cloud-sleuth/blob/59216c32f7848ec337fb68d1dbec8e87eeb6bf59/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/grpc/SpringAwareManagedChannelBuilder.java#L31-L34)。
+
+----------
+
+[<- 返回索引](index)
diff --git a/docs/zh-CN/client/configuration.md b/docs/zh-CN/client/configuration.md
new file mode 100644
index 000000000..3ffb81f7d
--- /dev/null
+++ b/docs/zh-CN/client/configuration.md
@@ -0,0 +1,114 @@
+# 配置
+
+[<- 返回索引](../index)
+
+本节描述您如何配置您的 grpc-spring-boot-starter 客户端。
+
+## 目录
+
+- [通过属性配置](#configuration-via-properties)
+ - [选择目标](#choosing-the-target)
+- [通过Beans 配置](#configuration-via-beans)
+ - [GrpcChannelConfigurer](#grpcchannelconfigurer)
+ - [StubTransformer](#stubtransformer)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- *配置*
+- [安全性](security)
+
+## 通过属性配置
+
+grpc-spring-boot-starter 可以通过 Spring 的 `@ConfigurationProperties` 机制来进行 [配置](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)
+
+您可以在这里找到所有内建配置属性:
+
+- [`GrpcChannelsProperties`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/config/GrpcChannelsProperties.html)
+- [`GrpcChannelProperties`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/config/GrpcChannelProperties.html)
+- [`GrpcServerProperties.Security`](https://static.javadoc.io/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/config/GrpcChannelProperties.Security.html)
+
+如果你希望阅读源代码,你可以查阅 [这里](https://github.com/yidongnan/grpc-spring-boot-starter/blob/master/grpc-client-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java#L58)。
+
+Channels 的属性都是以 `grpc.client.__name__.` 或 `grpc.client.__name__.security.` 为前缀。 Channel 的名称从 `@GrpcClient` 注解中获取。 如果您想要配置一些其他的选项,如为所有服务端设置可信证书,并可以使用 `GLOBAL` 作为名称。 单个 channel 的属性配置会覆盖全局配置。
+
+### 选择目标
+
+您可以使用以下属性指定目标服务器:
+
+````properties
+grpc.client.__name__.address=static://localhost:9090
+````
+
+目标服务器支持多种 schemes,您可以使用它们来指定目标服务器(优先级0(低) - 10(高)):
+
+- `static`(优先级 4): 一个简单的IP静态列表 (v4 和 v6), 可用于连接到服务端 (支持 `localhost`)。 例如:`static://192.168.1:8080,10.0.0.1:1337`
+- [`dns`](https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/internal/DnsNameResolver.java#L66)(优先级 5):解析并绑定到给定 DNS 名称的所有地址。 地址将被缓存,只有当现有连接被关闭 / 失败时才会刷新。 更多选项,例如 `SVC` 查找(对 kubernetes 有用),可以通过系统属性启用。 例如:`dns:///example.my.company`
+- `discovery` (优先级 6):(可选) 使用 Spring Cloud 的`DiscoveryClient` 去查找合适的目标。 在 `HeartbeatEvent` 的时候,连接将自动刷新。 使用 `gRPC.port` 元数据来确定端口,否则使用服务端口。 示例: `discovery:///service-name`
+- `self`(优先级 0):如果您使用 `grpc-server-spring-boot-starter` 并且不想指定自己的地址 / 端口,则可以使用 self 关键词作为 scheme 或者 address 。 这对于需要使用随机服务器端口以避免冲突的测试特别有用。 例如:`self`或`self:self`
+- `in-process`:这是一个特殊的方案,将使用 `InProcessChannelFactory` 来替代原有正常的 ChannelFactory。 并使用它连接到 [`InProcessServer`](../server/configuration#enabling-the-inprocessserver)。 例如:`in-process:foobar`
+- *custom*: 您可以通过 Java 的 `ServiceLoader` 或从 Spring 的应用上下文中选择要自定义的 [`NameResolverProvider`](https://javadoc.io/page/io.grpc/grpc-all/latest/io/grpc/NameResolverProvider.html) ,并将其注册到 `NameResolverRegistry` 上.
+
+如果您没有定义地址,它将按照如下方式被猜测:
+
+- 首先它将尝试使用它的名称 (``)
+- 如果您配置了默认方案,它将尝试下一个 (`:`)
+- 然后它将使用 `NameResolver.Factory` 委托的默认方案(见上面的优先级)
+
+> **注意:** 斜杠的数量很重要! 还要确保不要连接到普通的 web / REST / 非 grpc 服务器(端口)。
+
+[客户端安全性](security) 页面上解释了 `SSL` / `TLS` 和其他与安全相关的配置。
+
+## 通过Beans 配置
+
+虽然这个项目提供大多数功能作为配置选项,但有时会因为添加它的开销太高了,我们会选择没有添加它。 如果您觉得这是一项重要功能,请随意打开一项功能性 Pull Request。
+
+如果您要更改应用程序,而不是通过属性进行更改,则可以使用该项目中现有存在的扩展点。
+
+首先,大多数 bean 可以被自定义 bean 替换,您可以按照您想要的任何方式进行配置。 如果您不希望这么麻烦,可以使用 `GrpcChannelConfigurer` 和 `StubTransformer` 等类来配置 channels,stubs 和其他组件,它不会丢失这个项目所提供的任何功能。
+
+### GrpcChannelConfigurer
+
+gRPC 客户端配置器允许您将自定义配置添加到 gRPC 的 `ManagedChannelBuilder` 。
+
+````java
+@Bean
+public GrpcChannelConfigurer keepAliveClientConfigurer() {
+ return (channelBuilder, name) -> {
+ if (channelBuilder instanceof NettyChannelBuilder) {
+ ((NettyChannelBuilder) channelBuilder)
+ .keepAliveTime(30, TimeUnit.SECONDS)
+ .keepAliveTimeout(5, TimeUnit.SECONDS);
+ }
+ };
+}
+````
+
+> 注意,根据您的配置,在应用上下文中可能有不同类型的 `ManagedChannelBuilder` (例如`InProcessChannelFactory`)。
+
+### StubTransformer
+
+StubTransformer 允许您在注入您的 Bean 之前修改`Stub`。
+
+````java
+@Bean
+public StubTransformer call() {
+ return (name, stub) -> {
+ if ("serviceA".equals(name)) {
+ return stub.withWaitForReady();
+ } else {
+ return stub;
+ }
+ };
+}
+````
+
+## 附加主题
+
+- [入门指南](getting-started)
+- *配置*
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/client/getting-started.md b/docs/zh-CN/client/getting-started.md
new file mode 100644
index 000000000..788d766b5
--- /dev/null
+++ b/docs/zh-CN/client/getting-started.md
@@ -0,0 +1,144 @@
+# 入门指南
+
+[<- 返回索引](../index)
+
+本节讨论如何让 Spring 连接到 gRPC 服务端并管理您的连接。
+
+## 目录
+
+- [项目创建](#project-setup)
+- [依赖项](#dependencies)
+ - [接口项目](#interface-project)
+ - [服务端项目](#server-project)
+ - [客户端项目](#client-project)
+- [使用 Stubs 连接服务端](#using-the-stubs-to-connect-to-the-server)
+ - [解释客户端组件](#explaining-the-client-components)
+ - [访问客户端](#accessing-the-client)
+
+## 附加主题
+
+- *入门指南*
+- [配置](configuration)
+- [安全性](security)
+
+## 项目创建
+
+在我们开始添加依赖关系之前,让我们项目的一些设置建议开始。
+
+![project setup](/grpc-spring-boot-starter/assets/images/client-project-setup.svg)
+
+我们建议将您的项目分为2至3个不同的模块。
+
+1. **interface 项目** 包含原始 protobuf 文件并生成 java model 和 service 类。 你可能会在不同的项目中会共享这个部分。
+2. **Server 项目** 包含项目的业务实现,并使用上面的 Interface 项目作为依赖项。
+3. **Client 项目**(可选,可能很多) 任何使用预生成的 stub 来访问服务器的客户端项目。
+
+## 依赖项
+
+### 接口项目
+
+请参阅 [服务端入门指引](../server/getting-started#interface-project) 页面
+
+### 服务端项目
+
+请参阅 [服务端入门指引](../server/getting-started#server-project) 页面
+
+### 客户端项目
+
+#### Maven (客户端)
+
+````xml
+
+
+ net.devh
+ grpc-client-spring-boot-starter
+
+
+
+ example
+ my-grpc-interface
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+````
+
+#### Gradle (客户端)
+
+````gradle
+apply plugin: 'org.springframework.boot'
+
+dependencies {
+ compile('org.springframework.boot:spring-boot-starter')
+ compile('net.devh:grpc-client-spring-boot-starter')
+ compile('my-example:my-grpc-interface')
+}
+
+buildscript {
+ dependencies {
+ classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+ }
+}
+
+````
+
+## 使用 Stubs 连接服务端
+
+本节假定您已经定义并生成了[Protobuf](../server/getting-started#creating-the-grpc-service-definitions)。
+
+### 解释客户端组件
+
+- [`Channel`](https://javadoc.io/page/io.grpc/grpc-all/latest/io/grpc/Channel.html): Channel 是单个服务端的连接池。 目标服务器可能是多个 gRPC 服务。
+- [`ManagedChannel`](https://javadoc.io/page/io.grpc/grpc-all/latest/io/grpc/ManagedChannel.html): ManagedChannel 是 Channel 的一种特殊变体,因为它允许对连接池进行管理操作,例如将其关闭。
+- [`ClientInterceptor`](https://javadoc.io/page/io.grpc/grpc-all/latest/io/grpc/ClientInterceptor.html): 在每个 `Channel` 处理之前拦截它们。 可以用于日志、监测、元数据处理和请求/响应的重写。 grpc-spring-boot-starter 将自动接收所有带有 [`@GrpcGlobalClientInterceptor`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/interceptor/GrpcGlobalClientInterceptor.html) 注解以及手动注册在[`GlobalClientInterceptorRegistry`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/interceptor/GlobalClientInterceptorRegistry.html) 上的客户拦截器。
+- [`CallCredentials`](https://javadoc.io/page/io.grpc/grpc-all/latest/io/grpc/CallCredentials.html): 管理身份验证的组件。 它可以用于存储凭据和会话令牌。 它还可以用来身份验证,并且使用返回的令牌(例如 OAuth )来授权实际请求。 除此之外,如果令牌过期并且重新发送请求,它可以续签令牌。 如果您的应用程序上下文中只存在一个 `CallCredentials` bean,那么 spring 将会自动将其附加到`Stub`( **非** `Channel` )。 [`CallCredentialsHelper`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/security/CallCredentialsHelper.html)工具类可以帮助您创建常用的 `CallCredentials` 类型和相关的`StubTransformer`。
+- [`StubTransformer`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/inject/StubTransformer.html): 所有客户端的 `Stub` 的注入之前应用的转换器。
+- [`@GrpcClient`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/inject/GrpcClient.html): 这个注解用在你需要注入客户端的字段或者 set 方法上。 支持 `Channel`和各种类型的 `Stub`。 请不要将 `@GrpcClient` 与 `@Autowireed` 或 `@Inject` 一起使用。
+
+### 访问客户端
+
+我们建议注入 (`@GrpcClient`) `Stub`,而不是纯粹的 `Channel`.
+
+> **注意:** 存在不同类型的 `Stub`。 并非所有的都支持所有请求类型 (流式调用)。
+
+````java
+import example.HelloReply;
+import example.HelloRequest;
+import example.MyServiceGrpc;
+
+import io.grpc.stub.StreamObserver;
+
+import net.devh.boot.grpc.server.service.GrpcService;
+
+@Service
+public class FoobarService {
+
+ @GrpcClient("myService")
+ private MyServiceBlockingStub myServiceStub;
+
+ public String receiveGreeting(String name) {
+ HelloRequest request = HelloRequest.newBuilder()
+ .setName(name)
+ .build()
+ return myServiceStub.sayHello(request).getMessage();
+ }
+
+}
+````
+
+## 附加主题
+
+- *入门指南*
+- [配置](configuration)
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/client/security.md b/docs/zh-CN/client/security.md
new file mode 100644
index 000000000..bb7af1472
--- /dev/null
+++ b/docs/zh-CN/client/security.md
@@ -0,0 +1,115 @@
+# 客户端安全
+
+[<- 返回索引](../index)
+
+此页面描述了您如何连接到 gRPC 服务器并进行身份验证。
+
+## 目录
+
+- [启用传输图层安全](#enable-transport-layer-security)
+ - [基础要求](#prerequisites)
+- [禁用传输图层安全](#disable-transport-layer-security)
+ - [信任服务器](#trusting-a-server)
+- [双向证书认证](#mutual-certificate-authentication)
+- [身份验证](#authentication)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- *安全性*
+
+## 启用传输图层安全
+
+gRPC 默认使用 `TLS` 连接服务端,因此无需执行其他任何操作。
+
+如果您想要检查您是否意外覆盖配置, 请检查给定的属性有这样配置:
+
+````properties
+grpc.client..negotiationType=TLS
+````
+
+对于服务端的配置,请参考 [服务端安全](../server/security) 页面。
+
+### 基础要求
+
+如同往常一样,需要满足一些简单的前提条件:
+
+- 在您的 classpath 上有兼容的 `SSL `/`TLS` 实现
+ - 包含 [grpc-netty-shaded](https://mvnrepository.com/artifact/io.grpc/grpc-netty-shaded)
+ - 对于[`grpc-netty`](https://mvnrepository.com/artifact/io.grpc/grpc-netty),还需要额外添加 [`nety-tcnative-boringssl-static`](https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static) 依赖。 (请使用 [grpc-java的 Netty 安全部分](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty) 表中列出**完全相同** (兼容)的版本)。
+
+## 禁用传输图层安全
+
+> **警告:** 请勿在生产环境中这样做。
+
+有时您没有可用的证书(例如在开发期间),因此您可能希望禁用传输层安全,您可以这样做:
+
+````properties
+grpc.client.__name__.negotiationType=PLAINTEXT
+````
+
+下面的示例演示如何在测试中配置此属性:
+
+````java
+@SpringBootTest(properties = "grpc.client.test.negotiationType=PLAINTEXT")
+@SpringJUnitConfig(classes = TestConfig.class)
+@DirtiesContext
+public class PlaintextSetupTest {
+
+ @GrpcClient("test")
+ private MyServiceBlockingStub myService;
+````
+
+### 信任服务端
+
+如果您信任的证书不在常规信任存储区, 或者您想要限制您信任的 证书。您可以使用以下属性:
+
+````properties
+grpc.client.__name__.security.trustCertCollection=file:trusted-server.crt.collection
+````
+
+如果您想知道这里支持哪些选项,请阅读 [Spring 的 Resource 文档](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#resources-resourceloader)。
+
+如果您使用服务标识符,证书可能会出现问题,因为它对内部服务名称无效。 在这种情况下,您可以需要指定证书对哪个名字有效:
+
+````properties
+grpc.client.__name__.security.authorityOverride=localhost
+````
+
+## 双向证书认证
+
+在安全环境中,您可能必须使用客户端证书进行身份验证。 该证书通常由服务端提供,因此您需要为您的应用程序配置如下属性:
+
+````properties
+grpc.client.__name__.security.clientAuthEnabled=true
+grpc.client.__name__.security.certificateChain=file:certificates/client.crt
+grpc.client.__name__.security.privateKey=file:certificates/client.key
+````
+
+## 身份验证
+
+除了双向证书认证外,还有其他几种认证方式,如 `BasicAuth`。
+
+grpc-spring-boot-starter 除了一些帮助方法,同时提供了 BasicAuth 的实现。 然而,这里有很多库可以为 [`CallCredentials`](https://grpc.github.io/grpc-java/javadoc/io/grpc/CallCredentials.html)提供实现功能。 `CallCredentials` 是一个可扩展的组件,因为它们可以使用(第三方)服务队请求进行身份验证,并且可以自己管理和更新会话 token。
+
+如果您的应用程序上下文中只有一个`CallCredentials`,我们将自动为您创建一个 `StubTransformer`,并配置到所有的 `Stub`上。 如果您想为每个 Stub 配置不同的凭据,那么您可以使用 [`CallCredentialsHelper`](https://javadoc.io/page/net.devh/grpc-client-spring-boot-autoconfigure/latest/net/devh/boot/grpc/client/security/CallCredentialsHelper.html) 中提供的帮助方法。
+
+> **注意:** `StubTransformer` 只能自动配置注入的 `Stub`。 它们无法修改原始的 `Channel`。
+
+您还可以配置 `CallCredentials`(例如用于用户的凭据):
+
+````java
+MyServiceBlockingStub myServiceForUser = myService.withCallCredentials(userCredentials);
+return myServiceForUser.send(request);
+````
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- *安全性*
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/contributions.md b/docs/zh-CN/contributions.md
new file mode 100644
index 000000000..89c58d8ac
--- /dev/null
+++ b/docs/zh-CN/contributions.md
@@ -0,0 +1,13 @@
+# 参与贡献
+
+[<- 返回索引](index)
+
+我们始终欢迎您对项目作出任何贡献。
+
+详情请参阅我们的[贡献准则](https://github.com/yidongnan/grpc-spring-boot-starter/blob/master/CONTRIBUTING.md)。
+
+**感谢我们所有的[贡献者](https://github.com/yidongnan/grpc-spring-boot-starter/graphs/contributors)!**
+
+----------
+
+[<- 返回索引](index)
diff --git a/docs/zh-CN/examples.md b/docs/zh-CN/examples.md
new file mode 100644
index 000000000..99c69d10c
--- /dev/null
+++ b/docs/zh-CN/examples.md
@@ -0,0 +1,32 @@
+# 示例
+
+示例项目演示如何使用这些项目。
+
+这些项目可以作为您自己的项目的模板。 我们使用它们来验证这个库在不同的环境中运行,我们不会在不受注意的情况下改变它的行为。
+
+> **注意:** 如果您对这些项目有疑问,或者想要其他的示例,随时可以提出一个 [issue](https://github.com/yidongnan/grpc-spring-boot-starter/issues)。
+
+## 本地示例
+
+最简单的设置,使用本地服务端和一个或多个客户端
+
+- [服务端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/local-grpc-server)
+- [客户端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/local-grpc-client)
+- [说明](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples#local-mode)
+
+## Cloud 示例
+
+使用 eureka 服务发现的 Cloud 环境。
+
+- [Eureka 服务](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/cloud-eureka-server)
+- [服务端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/cloud-grpc-server)
+- [客户端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/cloud-grpc-client)
+- [说明](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples#cloud-mode)
+
+## 基础认证示例
+
+演示了 grpc 跟 spring security 的设置。 为了简单起见,此设置使用 Basic 身份验证,但也可以为其使用其他身份验证机制。
+
+- [服务端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/security-grpc-server)
+- [客户端](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples/security-grpc-client)
+- [说明](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/examples#with-basic-auth-security)
diff --git a/docs/zh-CN/index.md b/docs/zh-CN/index.md
new file mode 100644
index 000000000..825c04240
--- /dev/null
+++ b/docs/zh-CN/index.md
@@ -0,0 +1,24 @@
+# gRPC-Spring-Boot-Starter 文档
+
+gRPC-Spring-Boot-Starter 将 [Google的开源高性能RPC框架](https://grpc.io) 与 [Spring Boot 进行整合](https://spring.io/projects/spring-boot) 该项目简化了 gRPC 服务端 / 客户端的设置,只需要为项目添加了一个依赖项,并在服务实现类 / 客户 (stub) 字段上添加了一个的注解。 这个项目提供的特性仍然能复用您使用 gRPC 的经验,并且允许您执行任何自定义操作。
+
+## 目录
+
+- 服务端
+ - [入门指南](server/getting-started)
+ - [配置](server/configuration)
+ - [上下文数据 / Bean 的作用域](server/contextual-data)
+ - [测试服务](server/testing)
+ - [安全性](server/security)
+- 客户端
+ - [入门指南](client/getting-started)
+ - [配置](client/configuration)
+ - [安全性](client/security)
+- 其他设置
+- [疑难解答](trouble-shooting)
+- [示例项目](examples)
+- [版本概述](versions)
+- [支持 Spring Boot Actuator / Metrics](actuator)
+- [支持 Brave-Tracing / Spring Cloud Sleuth](brave)
+- [基准测试](benchmarking)
+- [参与贡献](contributions)
diff --git a/docs/zh-CN/server/configuration.md b/docs/zh-CN/server/configuration.md
new file mode 100644
index 000000000..6d2a9e62e
--- /dev/null
+++ b/docs/zh-CN/server/configuration.md
@@ -0,0 +1,108 @@
+# 配置
+
+[<- 返回索引](../index)
+
+本节描述您如何配置您的 grpc-spring-boot-starter 应用程序。
+
+## 目录
+
+- [通过属性配置](#configuration-via-properties)
+ - [更改服务端端口](#changing-the-server-port)
+ - [启用 InProcessServer](#enabling-the-inprocessserver)
+- [通过 Bean 配置](#configuration-via-beans)
+ - [GrpcServerConfigurer](#grpcserverconfigurer)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- *配置*
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- [安全性](security)
+
+## 通过属性配置
+
+grpc-spring-boot-starter 可以通过 Spring 的 `@ConfigurationProperties` 机制来进行 [配置](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)。
+
+您可以在这里找到所有内置配置属性:
+
+- [`GrpcServerProperties`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/config/GrpcServerProperties.html)
+- [`GrpcServerProperties.Security`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/config/GrpcServerProperties.Security.html)
+
+如果你希望阅读源代码,你可以查阅 [这里](https://github.com/yidongnan/grpc-spring-boot-starter/blob/master/grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/config/GrpcServerProperties.java#L50)。
+
+Channels 的属性都是以 `grpc.server..` 或 `grpc.client..security.` 为前缀。
+
+### 更改服务端端口
+
+如果您想要将 gRPC 服务端端口从默认值(`9090`) 更改为其他的端口,您可以这样做:
+
+````properties
+grpc.server.port=80
+````
+
+将端口设置为 `0` 以使用空闲的随机端口。 此功能用于部署了服务发现的服务和并行测试的场景。
+
+> 请确保您不会与其他应用程序或其他端点发生冲突,如`spring-web`。
+
+[服务端安全性](security) 页面上解释了 `SSL` / `TLS` 和其他与安全相关的配置。
+
+### 启用 InProcessServer
+
+有时,您可能想要在自己的应用程序中调用自己的 grpc 服务。 您可以像调用其他任何 gRPC 服务端一样,您需要使用 grpc 的 `InProcessServer` 来节省网络间开销。
+
+您可以使用以下属性将其打开:
+
+````properties
+grpc.server.in-process-name=
+# Optional: Turn off the external grpc-server
+#grpc.server.port=-1
+````
+
+这允许客户端在同一应用程序内使用以下配置连接到服务器:
+
+````properties
+grpc.client.inProcess.address=in-process:
+````
+
+这对测试特别有用,因为他们不需要打开特定的端口,因此可以并发运行(在构建 服务器上)。
+
+## 通过Beans 配置
+
+虽然这个项目提供大多数功能作为配置选项,但有时会因为添加它的开销太高了,我们会选择没有添加它。 如果您觉得这是一项重要功能,请随意打开一项功能性 Pull Request。
+
+如果您要更改应用程序,而不是通过属性进行更改,则可以使用该项目中现有存在的扩展点。
+
+首先,大多数 bean 可以被自定义 bean 替换,您可以按照您想要的任何方式进行配置。 如果您不希望这么麻烦,可以使用 `GrpcServerConfigurer` 来配置你的服务端和其他组件,它不会丢失这个项目所提供的任何功能。
+
+### GrpcServerConfigurer
+
+gRPC 服务端配置器允许您将自定义配置添加到 gRPC 的 `ServerBuilder` 。
+
+````java
+@Bean
+public GrpcServerConfigurer keepAliveServerConfigurer() {
+ return serverBuilder -> {
+ if (serverBuilder instanceof NettyServerBuilder) {
+ ((NettyServerBuilder) serverBuilder)
+ .keepAliveTime(30, TimeUnit.SECONDS)
+ .keepAliveTimeout(5, TimeUnit.SECONDS)
+ .permitKeepAliveWithoutCalls(true);
+ }
+ };
+}
+````
+
+> 注意,根据您的配置,在应用程序上下文中可能有不同类型的 `ServerBuilder` (例如`InProcessServerBuilder`)。
+
+## 附加主题
+
+- [入门指南](getting-started)
+- *配置*
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/server/contextual-data.md b/docs/zh-CN/server/contextual-data.md
new file mode 100644
index 000000000..6d8c14924
--- /dev/null
+++ b/docs/zh-CN/server/contextual-data.md
@@ -0,0 +1,64 @@
+# 上下文数据 / Bean 的作用域
+
+[<- 返回索引](../index)
+
+本节描述您如何保存请求上下文数据 / 每个请求的数据。
+
+## 目录
+
+- [警告语](#a-word-of-warning)
+- [grpcRequest 作用域](#grpcrequest-scope)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- *上下文数据 / Bean 的作用域*
+- [测试服务](testing)
+- [安全性](security)
+
+## 警告语
+
+在 grpc-java 中,消息发送 / 请求处理中的不同阶段可能在不同的线程中运行。 流式调用中也是这样。 避免在您的`ServerIntercetor` 和 grpc 服务方法实现中(在整个 gRPC 上下文中)使用 `ThreadLocal`。 When it comes down to it, the preparation phase, every single message and the completion phase might run in different threads. 如果您想要在会话中存储数据,请使用 grpc 的 `Context` 或 `grpcRequest` 作用域。
+
+## grpcRequest 作用域
+
+该项目添加了一个`grpcRequest`,该功能类似于 Spring Web 的`request` 作用域。 它只适用于单个的请求。
+
+首先需要用 `@Scope` 注解定义 Bean:
+
+````java
+@Bean
+@Scope(scopeName = "grpcRequest", proxyMode = ScopedProxyMode.TARGET_CLASS)
+//@Scope(scopeName = GrpcRequestScope.GRPC_REQUEST_SCOPE_NAME, proxyMode = ScopedProxyMode.TARGET_CLASS)
+ScopedBean myScopedBean() {
+ return new ScopedBean();
+}
+````
+
+> `proxyMode = TARGET_CLASS` 是必须的,除非在另一个 `grpcRequest` 作用域中配置了它. 请注意,这个`proxyMode` 不适用于 final 修饰的类和方法。
+
+之后,您就可以像以前那样使用 Bean:
+
+````java
+@Autowired
+private ScopedBean myScopedBean;
+
+@Override
+public void grpcMethod(Request request, StreamObserver responseObserver) {
+ responseObserver.onNext(myScopedBean.magic(request));
+ responseObserver.onCompleted();
+}
+````
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- *上下文数据 / Bean 的作用域*
+- [测试服务](testing)
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/server/getting-started.md b/docs/zh-CN/server/getting-started.md
new file mode 100644
index 000000000..f6640fb2a
--- /dev/null
+++ b/docs/zh-CN/server/getting-started.md
@@ -0,0 +1,302 @@
+# 入门指南
+
+[<- 返回索引](../index)
+
+本节描述了将您的应用程序接入 grpc-spring-boot-starter 项目的必要步骤。
+
+## 目录
+
+- [项目创建](#project-setup)
+- [依赖项](#dependencies)
+ - [接口项目](#interface-project)
+ - [服务端项目](#server-project)
+ - [客户端项目](#client-project)
+- [创建 gRPC 服务定义](#creating-the-grpc-service-definitions)
+- [实现服务逻辑](#implementing-the-service)
+
+## 附加主题
+
+- *入门指南*
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- [安全性](security)
+
+## 项目创建
+
+在我们开始添加依赖关系之前,让我们项目的一些设置建议开始。
+
+![project setup](/grpc-spring-boot-starter/assets/images/server-project-setup.svg)
+
+我们建议将您的项目分为2至3个不同的模块。
+
+1. **interface 项目** 包含原始 protobuf 文件并生成 java model 和 service 类。 你可能会在不同的项目中会共享这个部分。
+2. **Server 项目** 包含项目的业务实现,并使用上面的 Interface 项目作为依赖项。
+3. **Client 项目**(可选,可能很多) 任何使用预生成的 stub 来访问服务器的客户端项目。
+
+## 依赖项
+
+### 接口项目
+
+#### Maven (Interface)
+
+````xml
+
+
+ io.grpc
+ grpc-stub
+
+
+ io.grpc
+ grpc-protobuf
+
+
+
+ javax.annotation
+ javax.annotation-api
+
+
+
+
+
+
+ kr.motd.maven
+ os-maven-plugin
+
+
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+
+ com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
+ grpc-java
+ io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
+
+
+````
+
+#### Gradle (Interface)
+
+````gradle
+apply plugin: 'com.google.protobuf'
+
+dependencies {
+ compile "io.grpc:grpc-protobuf"
+ compile "io.grpc:grpc-stub"
+}
+
+protobuf {
+ protoc {
+ artifact = "com.google.protobuf:protoc:${protobufVersion}"
+ }
+ generatedFilesBaseDir = "$projectDir/src/generated"
+ clean {
+ delete generatedFilesBaseDir
+ }
+ plugins {
+ grpc {
+ artifact = "io.grpc:protoc-gen-grpc-java"
+ }
+ }
+ generateProtoTasks {
+ all()*.plugins {
+ grpc {}
+ }
+ }
+}
+
+buildscript {
+ dependencies {
+ classpath "com.google.protobuf:protobuf-gradle-plugin:${protobufGradlePluginVersion}"
+ }
+}
+
+// Optional
+eclipse {
+ classpath {
+ file.beforeMerged { cp ->
+ def generatedGrpcFolder = new org.gradle.plugins.ide.eclipse.model.SourceFolder('src/generated/main/grpc', null);
+ generatedGrpcFolder.entryAttributes['ignore_optional_problems'] = 'true';
+ cp.entries.add( generatedGrpcFolder );
+ def generatedJavaFolder = new org.gradle.plugins.ide.eclipse.model.SourceFolder('src/generated/main/java', null);
+ generatedJavaFolder.entryAttributes['ignore_optional_problems'] = 'true';
+ cp.entries.add( generatedJavaFolder );
+ }
+ }
+}
+
+// Optional
+idea {
+ module {
+ sourceDirs += file("src/generated/main/java")
+ sourceDirs += file("src/generated/main/grpc")
+ generatedSourceDirs += file("src/generated/main/java")
+ generatedSourceDirs += file("src/generated/main/grpc")
+ }
+}
+````
+
+### 服务端项目
+
+#### Maven (Server)
+
+````xml
+
+
+ net.devh
+ grpc-server-spring-boot-starter
+
+
+
+ example
+ my-grpc-interface
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+````
+
+#### Gradle (Server)
+
+````gradle
+apply plugin: 'org.springframework.boot'
+
+dependencies {
+ compile('org.springframework.boot:spring-boot-starter')
+ compile('net.devh:grpc-server-spring-boot-starter')
+ compile('my-example:my-grpc-interface')
+}
+
+buildscript {
+ dependencies {
+ classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+ }
+}
+
+````
+
+### 客户端项目
+
+请参阅 [客户端入门指引](../client/getting-started#client-project) 页面
+
+## 创建 gRPC 服务定义
+
+将您的 protobuf 定义/`.proto`文件放入`src/main/proto`。 有关编写 protobuf 文件的信息,请参阅官方的 [protobuf 文档](https://developers.google.com/protocol-buffers/docs/proto3)。
+
+您的 `.proto` 文件跟如下的示例类似:
+
+````proto
+syntax = "proto3";
+
+package net.devh.boot.grpc.example;
+
+option java_multiple_files = true;
+option java_package = "net.devh.boot.grpc.examples.lib";
+option java_outer_classname = "HelloWorldProto";
+
+// The greeting service definition.
+service MyService {
+ // Sends a greeting
+ rpc SayHello (HelloRequest) returns (HelloReply) {
+ }
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+ string name = 1;
+}
+
+// The response message containing the greetings
+message HelloReply {
+ string message = 1;
+}
+````
+
+配置 maven/gradle protobuf 插件使其调用 [`protoc`](https://mvnrepository.com/artifact/com.google.protobuf/protoc) 编译器,并使用 [`protoc-gen-grpc-java`](https://mvnrepository.com/artifact/io.grpc/protoc-gen-grpc-java) 插件并生成数据类、grpc 服务类 `ImplicBase`s 和 `Stub`。 请注意,其他插件,如 [reactive-grpc](https://github.com/salesforce/reactive-grpc) 可能会生成其他额外 / 替代类。 然而,它们也可以同样的方式使用。
+
+- `ImplicBase`类包含基本逻辑,映射虚拟实现到grpc 服务方法。 在 [实现服务逻辑](#implementing-the-service) 章节中有更多关于这个问题的信息。
+- `Stub`类是完整的客户端实现。 更多信息可以参考 [客户端指引](../client/getting-started) 页面。
+
+## 实现服务逻辑
+
+`protoc-gen-grpc-java` 插件为你的每个 grpc 服务生成一个类。 例如:`MyServiceGrpc` 的 `MyService` 是 proto 文件中的 grpc 服务名称。 这个类 包含您需要扩展的客户端 stub 和服务端的 `ImplicBase`。
+
+在这之后,你还有四个步骤:
+
+1. 请确保您的 `MyServiceImp` 实现了 `MyServiceGrpc.MyServiceImpBase`
+2. 将 `@GrpcService` 注解添加到您的 `MyServiceImp` 类上
+3. 请确保 `MyServiceImplic` 已添加到您的应用程序上下文中。
+ - 通过在您的 `@Configuration` 类中创建 `@Bean`
+ - 或者将其放置在 spring 的自动检测到路径中(例如在您`Main`类的相同或子包中)
+4. 实现 grpc 服务方法。
+
+您的 grpc 服务类将会看起来与下面的例子有些相似:
+
+````java
+import example.HelloReply;
+import example.HelloRequest;
+import example.MyServiceGrpc;
+
+import io.grpc.stub.StreamObserver;
+
+import net.devh.boot.grpc.server.service.GrpcService;
+
+@GrpcService
+public class MyServiceImpl extends MyServiceGrpc.MyServiceImplBase {
+
+ @Override
+ public void sayHello(HelloRequest request, StreamObserver responseObserver) {
+ HelloReply reply = HelloReply.newBuilder()
+ .setMessage("Hello ==> " + request.getName())
+ .build();
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+
+}
+````
+
+> **注意**: 理论上来说,不需要拓展 `ImplBase` 而是自己实现 `BindableService`。 但是,这样做可能会导致绕过 Spring Security 的检查。
+
+上面就是你接入过程中所有需要做的。 现在您可以启动您的 spring-boot 应用程序并开始向您的 grpc 服务发送请求。
+
+默认情况下,grpc-server 将使用 `PLAINTEXT` 模式在端口 `9090` 中启动。
+
+您可以通过运行 [grpcurl](https://github.com/fullstorydev/grpcurl) 命令来测试您的应用程序是否正常运行:
+
+````sh
+grpcurl --plaintext localhost:9090 list
+grpcurl --plaintext localhost:9090 list net.devh.boot.grpc.example.MyService
+grpcurl --plaintext -d '{"name": "test"}' localhost:9090 net.devh.boot.grpc.example.MyService/sayHello
+````
+
+## 附加主题
+
+- *入门指南*
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/server/security.md b/docs/zh-CN/server/security.md
new file mode 100644
index 000000000..3cb682534
--- /dev/null
+++ b/docs/zh-CN/server/security.md
@@ -0,0 +1,255 @@
+# 服务端安全
+
+[<- 返回索引](../index)
+
+本节描述如何使用传输层安全和身份验证来保护您的应用程序。 我们强烈建议至少启用运输层安全。
+
+## 目录
+
+- [启用传输图层安全](#enable-transport-layer-security)
+ - [基础要求](#prerequisites)
+ - [服务端配置](#configuring-the-server)
+- [双向证书认证](#mutual-certificate-authentication)
+- [认证和授权](#authentication-and-authorization)
+ - [配置身份验证](#configure-authentication)
+ - [配置授权](#configure-authorization)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- *安全性*
+
+## 启用传输图层安全
+
+您可以使用 Spring 的配置机制来配置传输层安全。 与之相关的非安全性配置选项参见 [配置](configuration) 页面。
+
+如果你的服务在 TLS 的反向代理后面,你可能不需要设置 `TLS/`。 如果您不熟悉安全,请咨询安全专家。 请不要忘记检查是否存在安全问题。 ^^
+
+> **注意: ** 请参考 [官方文档](https://github.com/grpc/grpc-java/blob/master/SECURITY.md) 以获取更多信息!
+
+### 基础要求
+
+- 在您的 classpath 上有兼容的 `SSL `/`TLS` 实现
+ - 包含 [grpc-netty-shaded](https://mvnrepository.com/artifact/io.grpc/grpc-netty-shaded)
+ - 对于[`grpc-netty`](https://mvnrepository.com/artifact/io.grpc/grpc-netty),还需要额外添加 [`nety-tcnative-boringssl-static`](https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static) 依赖。 (请使用 [grpc-java的 Netty 安全部分](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty) 表中列出**完全相同** (兼容)的版本)。
+- 带有私钥的证书
+
+#### 生成一个自签名的证书
+
+如果您没有证书(例如内部测试服务器),您可以使用`openssl`生成证书:
+
+````sh
+openssl req -x509 -nodes -subj "//CN=localhost" -newkey rsa:4096 -sha256 -keyout server.key -out server.crt -days 3650
+````
+
+请注意,如果没有额外配置,这些证书不受任何应用程序的信任。 我们建议您使用受全球CA或您公司CA信任的证书。
+
+### 服务端配置
+
+为了允许 grpc-server 使用 `TLS ` 您必须使用以下选项来配置它:
+
+````properties
+grpc.server.security.enabled=true
+grpc.server.security.certificateChain=file:certificates/server.crt
+grpc.server.security.privateKey=file:certificates/server.key
+#grpc.server.security.privateKeyPassword=MyStrongPassword
+````
+
+如果您想知道这里支持哪些选项,请阅读 [Spring 的 Resource 文档](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#resources-resourceloader)。
+
+对于客户端的配置,请参考 [客户端安全](../client/security) 页面。
+
+## 双向证书认证
+
+如果您想要确保只有可信的客户端能连接到服务端,您可以启用共同证书进行身份验证。 这允许或强制客户端使用`x509`证书验证自己。
+
+要启用相互身份验证,只需将以下属性添加到您的配置:
+
+````properties
+grpc.server.security.trustCertCollection=file:certificates/trusted-clients.crt.collection
+grpc.server.security.clientAuth=REQUIRE
+````
+
+您可以通过简单地绑定客户端证书创建 `trusted-clients.crt.collection` 文件:
+
+````sh
+cat client*.crt > trusted-clients.crt.collection
+````
+
+`客户端认证`模式定义了服务端的行为:
+
+- `REQUIRE` 客户端证书必须通过认证。
+- `OPTIONAL` 对客户端的证书进行身份验证,但不会强制这么做。
+
+如果您只想保护一些重要的服务或方法,您可以使用 `OPTIONAL`。
+
+尤其是在后一种情况下,适当的配置身份认证尤为重要。
+
+## 认证和授权
+
+`grpc-spring-boot-starter` 原生支持 `spring-security` , 因此您可以使用众所周知的一些注解来保护您的应用程序。
+
+![server-request-security](/grpc-spring-boot-starter/assets/images/server-security.svg)
+
+### 配置身份验证
+
+为了支持来自 grpc 客户端的身份验证,您必须定义客户端如何被允许进行身份验证。 您可以通过自定义 [`GrpcAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/GrpcAuthenticationReader.html) 来实现。
+
+grpc-spring-boot-starter 提供了一些内置实现:
+
+- [`AnonymousAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/AnonymousAuthenticationReader.html) Spring 的匿名身份认证。
+- [`BasicGrpcAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/BasicGrpcAuthenticationReader.html) 基础身份认证。
+- [`BearerAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/BearerAuthenticationReader.html) OAuth 以及类似协议的身份认证。
+- [`SSLContextGrpcAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/SSLContextGrpcAuthenticationReader.html) 基于证书的身份认证。
+- [`CompositeGrpcAuthenticationReader`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/authentication/CompositeGrpcAuthenticationReader.html) 依次尝试多个身份验证器。
+
+您 Bean 的定义将跟下面这个示例类似:
+
+````java
+@Bean
+public GrpcAuthenticationReader grpcAuthenticationReader() {
+ return new BasicGrpcAuthenticationReader();
+}
+````
+
+如果您想要强制用户使用 `CompositegrpcAuthenticationReader` ,而其中的一个`GrpcAuthenticationReader` 抛出一个`AuthenticationException`。 那么身份验证将失败,并且停止请求的处理。 如果 `GrpcAuthenticationReader` 返回 null,用户任然是未经验证。 如果身份验证器能够提取凭证/认证,则会交给 Spring 的`AuthenticationManager` 来管理。 由它来决定是否发送有效凭据,并且是否可以继续进行操作。
+
+#### 设置示例
+
+以下部分包含不同身份认证的配置示例:
+
+> 注意:不必在`CompositegrpcAuthenticationReader` 中包装阅读器,你可以直接添加多种机制。
+
+##### 基本认证
+
+````java
+@Bean
+AuthenticationManager authenticationManager() {
+ final List providers = new ArrayList<>();
+ providers.add(...); // Possibly DaoAuthenticationProvider
+ return new ProviderManager(providers);
+}
+
+@Bean
+GrpcAuthenticationReader authenticationReader() {
+ final List readers = new ArrayList<>();
+ readers.add(new BasicGrpcAuthenticationReader());
+ return new CompositeGrpcAuthenticationReader(readers);
+}
+````
+
+##### Bearer 认证 (OAuth2/OpenID-Connect)
+
+````java
+@Bean
+AuthenticationManager authenticationManager() {
+ final List providers = new ArrayList<>();
+ providers.add(...); // Possibly JwtAuthenticationProvider
+ return new ProviderManager(providers);
+}
+
+@Bean
+GrpcAuthenticationReader authenticationReader() {
+ final List readers = new ArrayList<>();
+ // The actual token class is dependent on your spring-security library (OAuth2/JWT/...)
+ readers.add(new BearerAuthenticationReader(accessToken -> new BearerTokenAuthenticationToken(accessToken)));
+ return new CompositeGrpcAuthenticationReader(readers);
+}
+````
+
+您也可能想要自定义 *GrantedAuthoritiesConverter* 来映射持有者 token 到权限 / 角色到 Spring Security 的 <>GrantedAuthority 中。
+
+##### 证书认证
+
+````java
+@Bean
+AuthenticationManager authenticationManager() {
+ final List providers = new ArrayList<>();
+ providers.add(new X509CertificateAuthenticationProvider(userDetailsService()));
+ return new ProviderManager(providers);
+}
+
+@Bean
+GrpcAuthenticationReader authenticationReader() {
+ final List readers = new ArrayList<>();
+ readers.add(new SSLContextGrpcAuthenticationReader());
+ return new CompositeGrpcAuthenticationReader(readers);
+}
+````
+
+另见[双向证书认证](#mutual-certificate-authentication)。
+
+### 配置授权
+
+这个步骤非常重要,因为它实际保护您的应用程序免受不必要的访问。 您可以通过两种方式保护您的 grpc 服务端。
+
+#### gRPC 安全检查
+
+保护应用程序安全的一种方式是将 [`GrpcSecurityMetadataSource`](https://javadoc.io/page/net.devh/grpc-server-spring-boot-autoconfigure/latest/net/devh/boot/grpc/server/security/check/GrpcSecurityMetadataSource.html) bean 添加到您的应用商家文中。 它允许您在每个 grpc 方法级别返回安全条件。
+
+一个示例 bean 定义 (使用硬代码规则) 可能如下所示:
+
+````java
+import net.devh.boot.grpc.server.security.check.AccessPredicate;
+import net.devh.boot.grpc.server.security.check.ManualGrpcSecurityMetadataSource;
+
+@Bean
+GrpcSecurityMetadataSource grpcSecurityMetadataSource() {
+ final ManualGrpcSecurityMetadataSource source = new ManualGrpcSecurityMetadataSource();
+ source.set(MyServiceGrpc.getMethodA(), AccessPredicate.authenticated());
+ source.set(MyServiceGrpc.getMethodB(), AccessPredicate.hasRole("ROLE_USER"));
+ source.set(MyServiceGrpc.getMethodC(), AccessPredicate.hasAllRole("ROLE_FOO", "ROLE_BAR"));
+ source.set(MyServiceGrpc.getMethodD(), auth -> "admin".equals(auth.getName()));
+ source.setDefault(AccessPredicate.denyAll());
+ return source;
+}
+
+@Bean
+AccessDecisionManager accessDecisionManager() {
+ final List> voters = new ArrayList<>();
+ voters.add(new AccessPredicateVoter());
+ return new UnanimousBased(voters);
+}
+````
+
+您必须配置 `AccessDecisionManager` 否则它不知道如何处理`AccessPredicate`。
+
+此方法的好处是您能够将配置移动到外部文件或数据库。 但是你必须自己实现。
+
+#### Spring 注解安全性检查
+
+当然,也可以仅仅使用 Spring Security 的注解。 对于这种情况,您必须将以下注解添加到您的某个 `@Configuration` 类中:
+
+````java
+@EnableGlobalMethodSecurity(___Enabled = true, proxyTargetClass = true)
+````
+
+> 请注意 `proxyTargetClass = true` 是必需的! 如果你忘记添加它,你会得到很多 `UNimpleneted` 的响应。 然而,您添加它将收到一个警告,`MyServiceImplic#bindService()` 方法是 final 修饰的。 **不要** 试图取消这些 final 修饰的方法,这将导致安全被绕过。
+
+然后您可以简单地在您的 grpc 方法上加注解:
+
+````java
+@Override
+@Secured("ROLE_ADMIN")
+// MyServiceGrpc.methodX
+public void methodX(Request request, StreamObserver responseObserver) {
+ [...]
+}
+````
+
+> 这个库假定你扩展 `ImplicBase` (由 grpc生成)来实现服务。 不这样做可能会导致绕过 Spring Security 的安全配置。
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- [测试服务](testing)
+- *安全性*
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/server/testing.md b/docs/zh-CN/server/testing.md
new file mode 100644
index 000000000..65388f2fa
--- /dev/null
+++ b/docs/zh-CN/server/testing.md
@@ -0,0 +1,283 @@
+# 测试服务
+
+[<- 返回索引](../index)
+
+本节介绍如何为您的 grpc-service 编写测试用例。
+
+## 目录
+
+- [前言](#introductory-words)
+- [测试服务](#the-service-to-test)
+- [有用的依赖项](#useful-dependencies)
+- [单元测试](#unit-tests)
+ - [独立测试](#standalone-tests)
+ - [基于Spring的测试](#spring-based-tests)
+- [集成测试](#integration-tests)
+
+## 附加主题
+
+- [入门指南](getting-started)
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- *测试服务*
+- [安全性](security)
+
+## 前言
+
+我们都知道测试对我们的应用程序是多么重要,所以我只会在这里向大家介绍几个链接:
+
+- [Testing Spring](https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html)
+- [Testing with JUnit](https://junit.org/junit5/docs/current/user-guide/#writing-tests)
+- [grpc-spring-boot-starter's Tests](https://github.com/yidongnan/grpc-spring-boot-starter/tree/master/tests/src/test/java/net/devh/boot/grpc/test)
+
+通常有两种方法来测试您的 grpc 服务:
+
+- [直接测试](#unit-tests)
+- [通过 grpc 测试](#integration-tests)
+
+## 测试服务
+
+让我们假设,我们希望测试以下服务:
+
+````java
+@GrpcService
+public class MyServiceImpl extends MyServiceGrpc.MyServiceImplBase {
+
+ private OtherDependency foobar;
+
+ @Autowired
+ public void setFoobar(OtherDependency foobar) {
+ this.foobar = foobar;
+ }
+
+ @Override
+ public void sayHello(HelloRequest request, StreamObserver responseObserver) {
+ HelloReply response = HelloReply.newBuilder()
+ .setMessage("Hello ==> " + request.getName())
+ .setCounter(foobar.getCount())
+ .build();
+ responseObserver.onNext(response);
+ responseObserver.onComplete();
+ }
+
+}
+````
+
+## 有用的依赖项
+
+在您开始编写自己的测试框架之前,您可能想要使用以下库来使您的工作更加简单。
+
+对于Maven来说,添加以下依赖:
+
+````xml
+<!-- JUnit-elotelFramework -->
+
+ org.junit。 upiter
+ junit-jupiter-api
+ test
+
+
+ org。 unit.jupiter
+ junit-jupiter-engine
+ test
+
+<- Grpc-extract Support -->
+
+ io. rpc
+ grpc-testing
+ test
+
+<! - Spring-Extract Support (Optional) -->
+
+ org。 pringframework.boot
+ spring-boot-start-test
+ test
+
+````
+
+Gradle 使用:
+
+````groovy
+// JUnit-Test-Framework
+testImplementation("org.junit.jupiter:junit-jupiter-api")
+testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
+// Grpc-Test-Support
+testImplementation("io.grpc:grpc-testing")
+// Spring-Test-Support (Optional)
+testImplementation("org.springframework.boot:spring-boot-starter-test")
+````
+
+## 单元测试
+
+在直接测试中,我们直接在 grpc-service bean/实例上调用方法。
+
+> 如果您自己创建的 grpc-service 实例, 请确保您先处理所需的依赖关系。 如果您使用Spring,它会处理您的依赖关系,但作为代价,您必须配置Spring。
+
+### 独立测试
+
+独立测试对外部库没有任何依赖关系(事实上你甚至不需要这个项目)。 然而,没有外部依赖关系并不总能使您的生活更加容易, 您可能需要复制其他库来执行您的行为。 使用 [Mockito](https://site.mockito.org) 这样的模拟库会简化你的流程,因为它限制依赖树的深度。
+
+````java
+public class MyServiceTest {
+
+ private MyServiceImpl myService;
+
+ @BeforeEach
+ public void setup() {
+ myService = new MyServiceImpl();
+ OtherDependency foobar = ...; // mock(OtherDependency.class)
+ myService.setFoobar(foobar);
+ }
+
+ @Test
+ void testSayHellpo() {
+ HelloRequest request = HelloRequest.newBuilder()
+ .setName("Test")
+ .build();
+ StreamRecorder responseObserver = StreamRecorder.create();
+ myService.sayHello(request, responseObserver);
+ if (!responseObserver.awaitCompletion(5, TimeUnit.SECONDS);
+ fail("The call did not terminate in time");
+ }
+ assertNull(responseObserver.getError());
+ List results = responseObserver.getValues().size();
+ assertEquals(1, results.size());
+ HelloReply response = results.get(0);
+ assertEquals(HelloReply.newBuilder()
+ .setMessage("Hello ==> Test")
+ .setCounter(1337)
+ .build(), response);
+ }
+
+}
+````
+
+### 基于Spring的测试
+
+如果您使用Spring来管理您自己的依赖关系,您实际上正在进入集成测试领域。 请确保您不要启动整个应用程序,而只提供所需的依赖关系为 (模拟) 的 Bean 类。
+
+> **注意:** 在测试期间,Spring 不会自动配置所有必须的 Bean。 您必须在有`@Configuration` 注解的类中手动创建它们。
+
+````java
+@SpringBootTest
+@SpringJUnitConfig(classes = { MyServiceUnitTestConfiguration.class })
+// Spring doesn't start without a config (might be empty)
+// Don't use @EnableAutoConfiguration in this scenario
+public class MyServiceTest {
+
+ @Autowired
+ private MyServiceImpl myService;
+
+ @Test
+ void testSayHellpo() {
+ HelloRequest request = HelloRequest.newBuilder()
+ .setName("Test")
+ .build();
+ StreamRecorder responseObserver = StreamRecorder.create();
+ myService.sayHello(request, responseObserver);
+ if (!responseObserver.awaitCompletion(5, TimeUnit.SECONDS);
+ fail("The call did not terminate in time");
+ }
+ assertNull(responseObserver.getError());
+ List results = responseObserver.getValues().size();
+ assertEquals(1, results.size());
+ HelloReply response = results.get(0);
+ assertEquals(HelloReply.newBuilder()
+ .setMessage("Hello ==> Test")
+ .setCounter(1337)
+ .build(), response);
+ }
+
+}
+````
+
+和所需的配置类:
+
+````java
+@Configuration
+public class MyServiceUnitTestConfiguration {
+
+ @Bean
+ OtherDependency foobar() {
+ // return mock(OtherDependency.class);
+ }
+
+ @Bean
+ MyServiceImpl myService() {
+ return new MyServiceImpl();
+ }
+
+}
+````
+
+## 集成测试
+
+然而,您有时需要测试整个调用栈。 例如,如果认证发挥了作用。 但在这种情况下,建议限制您的测试范围,以避免像 空数据库这样可能的外部影响。
+
+在这一点上,不使用 Spring 测试您的 Spring 应用程序是毫无意义的。
+
+> **注意:** 在测试期间,Spring 不会自动配置所有必须的 Bean。 您必须在有 `@Configuration` 注解修饰的类中手动创建他们,或显式的包含相关的自动配置类。
+
+````java
+@SpringBootTest(properties = {
+ "grpc.server.inProcessName=test", // Enable inProcess server
+ "grpc.server.port=-1", // Disable external server
+ "grpc.client.inProcess.address=in-process:test" // Configure the client to connect to the inProcess server
+ })
+@SpringJUnitConfig(classes = { MyServiceIntegrationTestConfiguration.class })
+// Spring doesn't start without a config (might be empty)
+@DirtiesContext // Ensures that the grpc-server is properly shutdown after each test
+ // Avoids "port already in use" during tests
+public class MyServiceTest {
+
+ @GrpcClient("inProcess")
+ private MyServiceBlockingStub myService;
+
+ @Test
+ @DirtiesContext
+ public void testSayHello() {
+ HelloRequest request = HelloRequest.newBuilder()
+ .setName("test")
+ .build();
+ HelloReply response = myService.sayHello(request);
+ assertNotNull(response);
+ assertEquals("Hello ==> Test", response.getMessage())
+ }
+
+}
+````
+
+所需的配置看起来像这样:
+
+````java
+@Configuration
+@ImportAutoConfiguration({
+ GrpcServerAutoConfiguration.class, // Create required server beans
+ GrpcServerFactoryAutoConfiguration.class, // Select server implementation
+ GrpcClientAutoConfiguration.class}) // Support @GrpcClient annotation
+public class MyServiceIntegrationTestConfiguration {
+
+ @Bean
+ OtherDependency foobar() {
+ return ...; // mock(OtherDependency.class);
+ }
+
+ @Bean
+ MyServiceImpl myServiceImpl() {
+ return new MyServiceImpl();
+ }
+
+}
+````
+
+> 注意:这个代码看起来可能比单元测试更短/更简单,但执行时间要长一些。
+
+## 附加主题- [入门指南](getting-started)
+- [配置](configuration)
+- [上下文数据 / Bean 的作用域](contextual-data)
+- *测试服务*
+- [安全性](security)
+
+----------
+
+[<- 返回索引](../index)
diff --git a/docs/zh-CN/trouble-shooting.md b/docs/zh-CN/trouble-shooting.md
new file mode 100644
index 000000000..ca54b308c
--- /dev/null
+++ b/docs/zh-CN/trouble-shooting.md
@@ -0,0 +1,268 @@
+# 疑难解答
+
+[<- 返回索引](index)
+
+本节描述这个项目的一些常见错误,以及如何解决这些错误。 请注意,这个页面永远不能覆盖所有案件,还请搜索现有的 issures/PRs(打开和关闭状态的)。 如果对应的主题已经存在,请给我们留下评论/信息,以便我们知道你也会受到影响。 如果没有这样的主题,请随时打开本页底部描述创建一个的新主题。
+
+## 目录
+
+- [传输失败](#transport-failed)
+- [网络因未知原因关闭](#network-closed-for-unknown-reason)
+- [找不到 TLS ALPN 提供商](#could-not-find-tls-alpn-provider)
+- [证书不匹配](#dismatching-certificates)
+- [不受信任的证书](#untrusted-certificates)
+- [服务端端口被占用](#server-port-already-in-use)
+- [创建 issues / 提问题](#creating-issues)
+
+## 传输失败
+
+### 服务端
+
+````txt
+2019-07-07 10:05:46.217 INFO 6552 --- [-worker-ELG-3-5] i.g.n.s.i.g.n.N.connections : Transport failed
+
+io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception: HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 16030100820100007e0303aae6126974cbb4638b325d6bdb
+ at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:85) ~[grpc-netty-shaded-1.21.0.jar:1.21.0]
+ at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.readClientPrefaceString(Http2ConnectionHandler.java:318) ~[grpc-netty-shaded-1.21.0.jar:1.21.0]
+ at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:251) ~[grpc-netty-shaded-1.21.0.jar:1.21.0]
+ at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:450) [grpc-netty-shaded-1.21.0.jar:1.21.0]
+````
+
+### 客户端
+
+````txt
+io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
+ at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:235)
+ at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:216)
+ at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:141)
+ at net.devh.boot.grpc.examples.lib.SimpleGrpc$SimpleBlockingStub.sayHello(SimpleGrpc.java:178)
+ [...]
+Caused by: io.grpc.netty.shaded.io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 00001204000000000000037fffffff000400100000000600002000000004080000000000000f0001
+ at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1204)
+ at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1272)
+ at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:502)
+````
+
+### 问题
+
+服务器运行在`PLAINTEXT`模式,但客户端试图在`TLS`(默认)模式中连接它。
+
+### 简单的解决办法
+
+将客户端配置在`PLAINTEXT`模式下连接(不推荐生产)。
+
+添加以下条目到您的客户端应用程序配置:
+
+````properties
+grpc.client.__name__.negotiationType=PLAINTEXT
+````
+
+### 更好的解决办法
+
+将服务端配置在`TLS`模式下运行(推荐)。
+
+添加以下条目到您的服务端应用程序配置:
+
+````properties
+grpc.server.security.enabled=true
+grpc.server.security.certificateChain=file:certificates/server.crt
+grpc.server.security.privateKey=file:certificates/server.key
+````
+
+## 网络因未知原因关闭
+
+### 客户端
+
+````txt
+io.grpc.StatusRuntimeException: UNAVAILABLE: Network closed for unknown reason
+````
+
+### 问题
+
+您可能是 (1) 尝试通过 `TLS ` 模式连接到 grpc-server 时,使用 `PLAINTE` 客户端 或 (2) 目标不是一个 grpc-server (例如 Web 服务)。
+
+### 解决办法
+
+1. 配置您的客户端使用`TLS`模式。
+
+ ````properties
+ grpc.client.__name__.negotiationType=TLS
+ ````
+
+ 或删除`negotiationType`配置,因为默认情况下`TLS`。
+2. 使用 `grpcurl` 或类似工具,验证已配置的服务端正在运行的是 grpc 服务
+
+## 找不到 TLS ALPN 提供商
+
+### 服务端
+
+````txt
+org.springframework.context.ApplicationContextException: Failed to start bean 'nettyGrpcServerLifecycle'; nested exception is java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available
+ at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
+ [...]
+Caused by: java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available
+ at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:258) ~[grpc-netty-1.21.0.jar:1.21.0]
+ at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:171) ~[grpc-netty-1.21.0.jar:1.21.0]
+ at io.grpc.netty.GrpcSslContexts.forServer(GrpcSslContexts.java:130) ~[grpc-netty-1.21.0.jar:1.21.0]
+ [...]
+````
+
+### 客户端
+
+````txt
+[...]
+Caused by: java.lang.IllegalStateException: Failed to create channel:
+ at net.devh.boot.grpc.client.inject.GrpcClientBeanPostProcessor.processInjectionPoint(GrpcClientBeanPostProcessor.java:118) ~[grpc-client-spring-boot-autoconfigure-2.4.0.RELEASE.jar:2.4.0.RELEASE]
+ at net.devh.boot.grpc.client.inject.GrpcClientBeanPostProcessor.postProcessBeforeInitialization(GrpcClientBeanPostProcessor.java:77)
+ [...]
+Caused by: java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available
+ at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:258) ~[grpc-netty-1.21.0.jar:1.21.0]
+ at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:171) ~[grpc-netty-1.21.0.jar:1.21.0]
+ at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:120) ~[grpc-netty-1.21.0.jar:1.21.0]
+ [...]
+````
+
+### 两端
+
+````txt
+AbstractMethodError: io.netty.internal.tcnative.SSL.readFromSSL()
+````
+
+### 问题
+
+classpath 上没有 (兼容) netty TLS 实现。
+
+### 解决办法
+
+从[`grpc-netty`](https://mvnrepository.com/artifact/io.grpc/grpc-netty)切换到[`grpc-netty-shaded`](https://mvnrepository.com/artifact/io.grpc/grpc-netty-shaded) 或添加依赖于[`nety-tcnative-boringssl-static`](https://mvnrepository.com/artifact/io.netty/netty-tcnative-boringssl-static) (请使用与[grpc-java 的netty 安全性部分](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty)**完全相同**(兼容的版本))。
+
+> **注意:** 你需要一个 64 位的 Java 虚拟机。
+
+## 证书不匹配
+
+### 客户端
+
+````txt
+io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
+[...]
+Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
+[...]
+Caused by: java.security.cert.CertificateException: No subject alternative names present
+````
+
+或
+
+````txt
+io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
+[...]
+Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
+[...]
+Caused by: java.security.cert.CertificateException: No name matching found
+````
+
+### 问题
+
+证书与目标地址/名称不匹配。
+
+### 解决办法
+
+通过在客户端配置中添加以下内容:
+
+````properties
+grpc.client.__name__.security.authorityOverride=
+````
+
+## 不受信任的证书
+
+### 客户端
+
+````txt
+io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
+[...]
+Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
+[...]
+Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
+[...]
+Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
+````
+
+### 问题
+
+服务器使用的证书不在客户端的信任库中。
+
+### 解决办法
+
+通过使用 java `keytool` 将证书添加到java的信任商店,或配置客户端使用自定义信任的证书文件:
+
+````properties
+grpc.client.__name__.security.trustCertCollection=file:certificates/trusted-servers-collection.crt.list
+````
+
+> **注意:** 两边的存储库目前在创建时都是只读的,更新不会被应用。
+
+## 服务端端口被占用
+
+### 服务端
+
+````txt
+Caused by: java.lang.IllegalStateException: Failed to start the grpc server
+ at net.devh.boot.grpc.server.serverfactory.GrpcServerLifecycle.start(GrpcServerLifecycle.java:51) ~[grpc-server-spring-boot-autoconfigure-2.4.0.RELEASE.jar:2.4.0.RELEASE]
+ [...]
+Caused by: java.io.IOException: Failed to bind
+ at io.grpc.netty.shaded.io.grpc.netty.NettyServer.start(NettyServer.java:246) ~[grpc-netty-shaded-1.21.0.jar:1.21.0]
+ at io.grpc.internal.ServerImpl.start(ServerImpl.java:177) ~[grpc-core-1.21.0.jar:1.21.0]
+ at io.grpc.internal.ServerImpl.start(ServerImpl.java:85) ~[grpc-core-1.21.0.jar:1.21.0]
+ at net.devh.boot.grpc.server.serverfactory.GrpcServerLifecycle.createAndStartGrpcServer(GrpcServerLifecycle.java:90) ~[grpc-server-spring-boot-autoconfigure-2.4.0.RELEASE.jar:2.4.0.RELEASE]
+ at net.devh.boot.grpc.server.serverfactory.GrpcServerLifecycle.start(GrpcServerLifecycle.java:49) ~[grpc-server-spring-boot-autoconfigure-2.4.0.RELEASE.jar:2.4.0.RELEASE]
+ ... 13 common frames omitted
+Caused by: java.net.BindException: Address already in use: bind
+````
+
+### 问题
+
+grpc 服务端尝试使用的端口被占用。
+
+有四种常见情况可能发生这种错误。
+
+1. 应用程序已在运行
+2. 另一个应用程序正在使用该端口
+3. grpc 服务器使用了一个已经用于其他用途的端口(例如spring-web)
+4. 你正在运行测试,每次测试后你都没有关闭 grpc-server
+
+### 解决办法
+
+1. 尝试使用任务管理器或`jps`搜索应用程序
+2. 尝试使用 `netstat` 搜索端口
+3. 检查/更改您的配置。 此库默认使用端口 `9090`
+4. 添加`@DirtiesContext`到您的测试类和方法中,请注意,这个错误只会从第二次测试开始发生,因此你必须在你的第一个测试类上也加上这个注解!
+
+## 创建 issue
+
+在 GitHub 上创建问题/提问并不难,但你可以稍微努力帮助我们更快地解决您的 个问题。
+
+如果您的问题/疑问一般都是关于 grpc 的问题,请考虑在 [grpc-java](https://github.com/grpc/grpc-java) 上提问。
+
+使用提供的模板来创建新问题,其中包含我们需要的必需/有用信息的部分。
+
+通常来说,你应该在你的问题上包括以下信息:
+
+1. 您有什么类型的诉求?
+ - 问题
+ - Bug 反馈
+ - 功能请求
+2. 你希望的结果是什么?
+3. 问题是什么? 什么不起作用? 缺少什么东西,为什么需要?
+4. 任何相关堆栈/日志(非常重要)
+5. 您使用的是哪个版本?
+ - Spring (boot)
+ - grpc-java
+ - grpc-spring-boot-starter
+ - 其他相关库
+6. 其他背景
+ - 它以前是否正常运行过?
+ - 我们如何重现?
+ - 有 demo 演示吗?
+
+----------
+
+[<- 返回索引](index)
diff --git a/docs/zh-CN/versions.md b/docs/zh-CN/versions.md
new file mode 100644
index 000000000..a949cabc8
--- /dev/null
+++ b/docs/zh-CN/versions.md
@@ -0,0 +1,81 @@
+# 版本
+
+[<- 返回索引](index)
+
+此页显示关于我们版本策略和生命周期等额外信息。
+
+## 目录
+
+- [版本策略](#versioning-policy)
+- [版本列表](#version-table)
+ - [2.x 版本](#version-2x)
+ - [1.x 版本](#version-1x)
+ - [升级依赖关系](#upgrading-dependencies)
+ - [发布日志](#release-notes)
+
+## 版本策略
+
+这个项目的主要版本定义了我们与哪个Spring-boot版本兼容。
+
+- 1.x.x 版本为 EOL,不会再收到任何更新。
+- 2.x.x 是当前的维护版本,如果有 spring-boot 或者 gRPC 版本,将进行更新。
+
+次版本定义了此项目的功能版本。 每次我们更改 spring boot 或 gRPC 版本时,我们也会增加我们的功能版本。 如果我们增加/改变主要特征,也是如此。 在大多数情况下,你不会通过升级获得任何不兼容之处,但因为gRPC 就像它的 API 一样, 这个问题不能被排除在外。 我们试图尽量减少这种影响,但不能排除这种影响。 如果您不使用高级功能,您通常不会收到通知。
+
+我们通常不发布补丁版本,但在下次发布时包含这些补丁。 如果你需要一个修补过的版本,请新开一个 issue。
+
+## 版本列表
+
+下表显示了该项目和 spring boot 以及 gRPC 版本的关系。 在大多数情况下,你可以升级到较新的版本,但如果是 gRPC 改变了其 API。 请将任何问题报告给我们[仓库](https://github.com/yidongnan/grpc-spring-boot-starter/issues)。
+
+> **注意**
+>
+> 如果您正在使用 non-shaded netty(和相关的库),请 **严格** 保持这些版本跟 gRPC [文档](https://github.com/grpc/grpc-java/blob/master/SECURITY.md#netty) 一致。 (grpc-netty-shaded 通过保持这些版本同步来避免这些问题。)
+
+### 2.x 版本
+
+当前版本。
+
+| 版本 | spring-boot | gRPC | 日期 |
+|:-------:|:-----------:|:------:| --------:|
+| 2.6.0 * | 2.2.1 | 1.24.2 | 待定 |
+| 2.5.1 | 2.1.6 | 1.22.2 | 2018年8月 |
+| 2.5.0 | 2.1.6 | 1.22.1 | 2018年8月 |
+| 2.4.0 | 2.1.5 | 1.20.0 | 2019年6月 |
+| 2.3.0 | 2.1.4 | 1.18.0 | 2019年4月 |
+| 2.2.1 | 2.0.7 | 1.17.1 | 2019年1月 |
+| 2.2.0 | 2.0.6 | 1.17.1 | 2018年12月 |
+| 2.1.0 | 2.0.? | 1.14.0 | 2018年10月 |
+| 2.0.1 | 2.0.? | 1.14.0 | 2018年8月 |
+| 2.0.0 | 2.0.? | 1.13.1 | 2018年8月 |
+
+(* 未来版本)
+
+### 1.x 版本
+
+生命终结——没有计划的更新。
+
+| 版本 | spring-boot | gRPC | 日期 |
+|:-----:|:-----------:|:------:| -------:|
+| 1.4.2 | 1.?.? | 1.12.0 | 2019年6月 |
+| 1.4.1 | 1.?.? | 1.12.0 | 2018年6月 |
+| ... | 1.?.? | N/A | |
+
+### 升级依赖关系
+
+如果你升级任何版本,我们强烈建议使用 bom 文件进行升级:
+
+- [spring-boot](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent)
+- [grpc-java](https://mvnrepository.com/artifact/io.grpc/grpc-bom)
+
+### 发布日志
+
+有关每个版本的更改,请参考发行说明。
+
+- [grpc-spring-boot-starter](https://github.com/yidongnan/grpc-spring-boot-starter/releases)
+- [spring-boot](https://github.com/spring-projects/spring-boot/releases)
+- [grpc-java](https://github.com/grpc/grpc-java/releases)
+
+----------
+
+[<- 返回索引](index)