Spring-Cloud-应用接入
服务注册与发现
准备工作
- 开发环境中下载Maven并完成环境配置。
- 开发环境中安装JDK1.8并完成环境配置(目前项目仅支持1.8)。
- 我们提供了简单的demo样例可供您快速开始了解并体验我们的平台:服务提供者样例 、服务消费者样例。
创建服务提供者
在本地创建一个服务提供者工程,添加微服务注册发现依赖,开启服务注册与发现功能。并将自身通过微服务平台注册到服务注册中心。
1.创建provider工程
创建一个Maven工程,命名为provider-demo,JDK选择1.8版本。
2.修改pom文件,添加Spring Cloud和微服务依赖
微服务支持Spring boot 2.0.7.REALEASE及以上版本和Spring Cloud Finchley.SR2 及以上版本。 这里以Spring boot 2.0.7.REALEASE 和 Spring Cloud Finchley.SR2为例。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<relativePath/>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baidubce.formula</groupId>
<artifactId>spring-cloud-formula-cnap</artifactId>
<version>{spring-cloud-formula.version}</version>
</dependency>
</dependencies>
说明:Spring boot 2.0.7.REALEASE之前的版本存在许多已知的问题,如原有程序版本低于该版本建议升级到2.0.7.REALEASE或以上版本;
spring-cloud-formula-cnap包含对接入CNAP微服务平台所需的全部功能包,{spring-cloud-formula.version}为版本号,可自行在Maven仓库中查找使用最新版本。
3.开发服务提供者启动类,开启服务注册发现功能
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
@EnableDiscoveryClient注解用于开启服务注册与发现功能
4.创建简单的Controller,包含一个方法获取URL中的参数。
@RestController
@RequestMapping(value = "/echo")
public class EchoController {
@RequestMapping(value = "/{message}", method = RequestMethod.GET)
public String echo(@PathVariable String message) {
return message;
}
}
5.配置application.properties配置文件
在application.properties中添加如下配置:
# 服务名称
spring.application.name=provider-demo
server.port=10001
创建服务消费者
本示例中创建一个服务消费者,添加服务发现的依赖,同时分别通过RestTemplate、AsyncRestTemplate、FeignClient这三个客户端去调用服务提供者。
1.创建Consumer工程
创建一个Maven项目,命名为consumer-demo,JDK选择1.8版本。
2.修改pom文件,添加Spring Cloud的依赖
微服务支持Spring boot 2.0.7.REALEASE及以上版本和Spring Cloud Finchley.SR2 及以上版本。 这里以Spring boot 2.0.7.REALEASE 和 Spring Cloud Finchley.SR2为例。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<relativePath/>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baidubce.formula</groupId>
<artifactId>spring-cloud-formula-cnap</artifactId>
<version>{spring-cloud-formula.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
相比于服务提供者,这里多添加了对spring-cloud-starter-openfeign的依赖,是因为我们需要演示FeignClient的使用。
3.开发服务消费者启动类,开启服务发现功能
需要使用RestTemplate、AsyncRestTemplate、FeignClient三个客户端的使用,因此需要额外添加配置:
- 添加@LoadBalance注解将RestTemplate、AsyncRestTemplate与服务发现集成
-
@EnableFeignClients注册激活FeignClient
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } @LoadBalanced @Bean public AsyncRestTemplate asyncRestTemplate(){ return new AsyncRestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); }
}
4.创建一个FeignClient接口
@FeignClient(name = "provider-demo")
public interface EchoService {
@RequestMapping(value = "/echo/{message}", method = RequestMethod.GET)
String echo(@PathVariable("message") String message);
}
FeignClient的名称provider-demo为服务提供者工程中配置的服务名(spring.application.name)
5.创建一个测试Controller以演示和进行服务发现
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private AsyncRestTemplate asyncRestTemplate;
@Autowired
private EchoService echoService;
@RequestMapping(value = "/echo-rest/{message}", method = RequestMethod.GET)
public String rest(@PathVariable String message) {
return restTemplate.getForObject("http://provider-demo/echo/" + message, String.class);
}
@RequestMapping(value = "/echo-async-rest/{message}", method = RequestMethod.GET)
public String asyncRest(@PathVariable String message) throws Exception{
ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.
getForEntity("http://provider-demo/echo/"+message, String.class);
return future.get().getBody();
}
@RequestMapping(value = "/echo-feign/{message}", method = RequestMethod.GET)
public String feign(@PathVariable String message) {
return echoService.echo(message);
}
}
6.修改配置
修改application.properties配置信息:
spring.application.name=consumer-demo
server.port=10002
本地开发与调试
具体请参考:轻量级注册中心接入
本地IDE中启动
分别执行provider-demo和consumer-demo的main方法进行启动。
正常场景中程序会启动完毕,如遇到启动出错情况,建议在程序启动参数 Program arguement 中增加如下参数,用于打印更详细的输出信息
--logging.level.org.apache=debug
FatJar启动
1.maven中配置打包插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.打包FatJar文件
分别在consumer-demo、provider-demo的工程主路径下,使用 mvn clean package 进行打包,将在target目录下生成可执行的jar文件。
3.通过java命令执行FatJar
进入部署的K8S POD中,执行如下命令:
java -jar consumer-demo-1.0-SNAPSHOT.jar
java -jar provider-demo-1.0-SNAPSHOT.jar
服务验证
分别调用以下接口,观察调用返回是否符合预期
http://{consumer-demo-ip}:{consumer-demo-port}/echo-rest/hello
http://{consumer-demo-ip}:{consumer-demo-port}/echo-async-rest/hello
http://{consumer-demo-ip}:{consumer-demo-port}/echo-feign/hello
CNAP平台部署
1.制作镜像
参考镜像制作文档
注意:若需要使用微服务平台的监控功能,请按照该文档步骤进行镜像制作。
2.使用CNAP平台进行部署
请参考CNAP操作手册中的服务部署部分。
3.检查部署结果
成功部署后将在CNAP平台 – 服务列表页中看到注册上的服务信息
路由
服务路由原理
1.服务路由概述
服务路由是指在某个作用域(工作空间+环境),用户可以配置路由规则,将服务消费者的流量路由到规则中指定的服务提供者实例。
目前CNAP服务路由支持以下配置方式:
- 按照系统标签进行路由规则的配置。CNAP中运行的服务预先设置的系统标签,如服务的部署组等信息。 用户可以配置路由规则,将服务消费者某个部署组的流量分配到服务提供方的确定部署组上进行处理,以满足服务路由的需求。
开启路由功能
路由功能需要用户在代码中添加相关依赖,以开启服务路由的功能。
1.配置路由模块依赖
<dependency>
<groupId>com.baidubce.formula</groupId>
<artifactId>spring-cloud-formula-cnap</artifactId>
<version>{spring-cloud-formula.version}</version>
</dependency>
此时即对本程序开启了路由功能,配合CNAP产品控制台上的路由管理功能,即可按照配置的规则进行服务路由。如已经引入,可不需要重新引入。
注意:若使用路由功能,则需在服务消费者端配置。
此时用户代码已经具备了服务路由的功能,需要配合控制台上设置路由规则,以查看路由效果。需要代码编写完成后进行镜像的打包上传(参考镜像制作),并在CNAP平台部署运行。
2.在CNAP平台中部署与配置
2.1 部署
服务路由功能至少需要创建两个应用,一个作为服务提供者provider(以provider-demo为例),另一个作为服务消费者consumer(以consumer-demo为例)。
并且consumer应用至少部署一个部署组Group-C1,provider应用至少部署两个部署组Group-P1和Group-P2。具体部署操作参考操作指南。
2.2 配置
操作:
1、登录CNAP产品控制台。
2、从左侧菜单栏,进入微服务管理-服务列表。
3、选择目标服务provider-demo,从【操作】的【路由】 进入路由列表页面。
4、点击【添加路由规则】,配置路由规则。
进入路由配置页面后,填写基础信息规则名称。
流量来源中服务名称我们选择consumer-demo,指定来源的标签为应用名,选择其值为consumer,意味着这条路由规则将在服务consumer-demo所在的应用consumer的所有实例生效。
流量目的中服务名默认为provider-demo,分配策略选择权重。在权重路由时,我们可以选择标签为部署组,其值可选择provider的两个部署组,为了使得演示更加明显,我们设置provider应用的部署组Group-P1的权重为100,provider应用的部署组Group-P2的权重为0,负载均衡策略可选择随机。这些配置意味着consumer-demo服务访问provider-demo服务时,期望流量完全分配至应用provider的部署组Group-P1,而部署组Group-P2将不会有流量。若Group-P1部署组下存在多个实例时,则选择的负载均衡策略为随机。
验证路由功能
从consumer端发起对provider的调用,由于路由规则的下发与生效约存在30秒的延迟,建议consumer持续发起对provider的请求。
若provider的不同部署组中代码逻辑会产生不同的返回结果,可以通过返回结果信息验证路由功能。也可以通过观察provider服务监控页面中的PV图的变化验证。
限流
限流功能原理
在服务提供者端代码中添加限流依赖,在CNAP控制台中配置限流规则。
30秒内规则生效后,服务消费者调用服务提供者时,所有的访问将先通过限流模块。到达限流模块后,先判断该请求是否满足限流规则对应的限流方法,再检查是否满足限流规则配置的来源,当两者都满足后,再判断当前请求是否达到该限流规则的限流阈值。
若超过了限流阈值,服务提供者端将直接返回,http状态码为429 Too many request。
CNAP的限流功能维度为:方法级与实例级。在配置有相应限流规则的前提下,通过特定算法,保证在流量较大时,服务提供者按照一定阈值平滑处理请求。
开启限流功能
限流功能开启需要在服务提供者程序代码中添加限流功能模块,使服务提供者具备限流控制的功能。 开启步骤如下:
1.配置限流模块依赖
<dependency>
<groupId>com.baidubce.formula</groupId>
<artifactId>spring-cloud-formula-cnap</artifactId>
<version>{spring-cloud-formula.version}</version>
</dependency>
添加完该依赖后provider端将引入限流功能的模块组件。
此时本服务提供者应用具有了服务限流的功能,所有的请求会经过限流模块,该服务节点上的配额使用完后进行限流,响应429: Too Many Reqeusts。
限流功能需配置CNAP控制台进行配置下发,因此代码编写完成后需进行镜像的打包与上传(参考镜像制作),并在CNAP平台部署。
2.在CNAP平台部署与配置
代码编写与镜像制作完成后,需要在CNAP平台中进行部署,并使用限流管理功能配置限流规则。 CNAP平台中进行应用的部署与启动,参考操作指南。
操作:
1、登录CNAP产品控制台。
2、从左侧菜单栏,进入服务治理-服务列表。
3、选择目标服务(服务提供方),从【操作】的【限流】 进入限流列表页面。
4、点击【添加限流规则】,配置规则。
选择限流对象的应用名与部署组,以及要限流的URL与httpMethod,CNAP限流粒度为httpMethod + uri。对于该限流规则,可以进一步配置流量来源(如服务名等于consumer-demo),默认可以不用配置来源,即该限流规则对所有来源限流。
uri:可以是完整的uri,也可以是带uri参数的url(如/echo/{message}),建议与provider代码中requestMapping中定义的uri一致,以方便验证接入限流功能。
验证限流功能
如配置了流量来源为指定服务consumer的限流规则,则从该consumer端持续发起对指定provider的URL的调用,当单位时间内请求量超过指定QPS阈值时,consumer端则收到429状态码。
熔断
熔断功能原理
熔断的功能为当某个目标服务调用慢或者有大量失败时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。后续如果目标服务情况好转则恢复调用。
熔断分为主动熔断和自动熔断,主动熔断会熔断消费者所有的请求,自动熔断时依据历史请求结果判定后续请求是否熔断。
若熔断开启,请求不会发送出去,直接返回,http状态码为500 CircuitBreaker is open。
CNAP的熔断功能维度为:方法维度、服务维度熔断。
- 方法维度含义为可以为目标服务的具体方法配置熔断规则,该规则针对当前方法生效,与其他方法互不影响,目前方法支持HttpMethod+URL
- 服务维度含义为可针对目标服务配置熔断规则,规则对向该服务发起的所有请求都有效。
开启熔断功能
熔断功能开启需要在服务消费者程序代码中添加熔断功能模块,使服务消费者具备熔断控制的功能。 开启步骤如下:
1.配置熔断模块依赖
<dependency>
<groupId>com.baidubce.formula</groupId>
<artifactId>spring-cloud-formula-cnap</artifactId>
<version>{spring-cloud-formula.version}</version>
</dependency>
添加完该依赖后consumer端将引入熔断功能的模块组件。
此时本服务消费者应用具有了请求熔断的功能,所有的请求会先经过熔断模块,若熔断开启,请回会直接返回500: CircuitBreaker is open。
熔断功能需配置CNAP控制台进行配置下发,因此代码编写完成后需进行镜像的打包与上传(参考镜像制作),并在CNAP平台部署。
2.在CNAP平台部署与配置
代码编写与镜像制作完成后,需要在CNAP平台中进行部署,并使用熔断管理功能配置熔断规则。
CNAP平台中进行应用的部署与启动,参考操作指南。
操作:
1、登录CNAP产品控制台。
2、从左侧菜单栏,进入服务治理-服务列表。
3、选择目标服务,从【操作】的【熔断】 进入熔断列表页面。
4、点击【添加熔断规则】,配置规则。
熔断对象支持标签选择,也可以不配置标签删选条件。如果不配置删选条件,该熔断对所有的consumer服务生效。
CNAP限流粒度为服务端服务名 + httpMethod + uri。 uri:可以是完整的uri,也可以是带uri参数的url(如/echo/{message}),建议与服务提供端代码中requestMapping中定义的uri一致,以方便验证接入熔断功能。
验证熔断功能
从consumer端发起对provider的调用,熔断规则的下发与生效存在至多30秒的延迟 若对provider的请求返回异常,达到熔断条件后,可以从请求结果观察到熔断生效;也可以开启手动熔断,直接熔断所有对provider的请求。