springcloud高级
第一章 负载均衡 Ribbon
(Spring Cloud 高级)
一、 Ribbon 在微服务中的作用
1 什么是 Ribbon
1.Ribbon 是一个基于 Http 和 TCP 的客服端负载均衡工具,它是基于 Netflix Ribbon 实
现的。
2.它不像 spring cloud 服务注册中心、配置中心、API 网关那样独立部署,但是它几乎
存在于每个 spring cloud 微服务中。包括 feign 提供的声明式服务调用也是基于该 Ribbon
实现的。
3.ribbon 默认提供很多种负载均衡算法,例如 轮询、随机 等等。甚至包含自定义的负
载均衡算法。
2 Ribbon 解决了什么问题
他解决并提供了微服务的负载均衡的问题。
二、 集中式与进程内负载均衡的区别
1 负载均衡解决方案的分类
目前业界主流的负载均衡方案可分成两类:
第一类:集中式负载均衡, 即在 consumer 和 provider 之间使用独立的负载均衡设施(可
以是硬件,如 F5, 也可以是软件,如 nginx), 由该设施负责把 访问请求 通过某种策略转发
至 provider;
第二类:进程内负载均衡,将负载均衡逻辑集成到 consumer,consumer 从服务注册中
心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的 provider。
Ribbon 就属于后者,它只是一个类库,集成于 consumer 进程,consumer 通过它来获取
到 provider 的地址。
2 两种负载均衡方式结构图
三、 Ribbon 的入门案例
Ribbon 中对于集群的服务采用的负载均衡的策略默认的是轮询
1 Consumer
@Service public class UserService { @Autowired private LoadBalancerClient loadBalancerClient;//ribbon 负 载均衡器 public List<User> getUsers(){ //选择调用的服务的名称 //ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("eureka-provider"); //拼接访问服务的 URL StringBuffer sb = new StringBuffer(); //http://localhost:9090/user sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/user"); System.out.println(sb.toString()); //springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {}; //ResponseEntity:封装了返回值信息 ResponseEntity<List<User>> response = rt.exchange(sb.toString(),HttpMethod.GET, null, type); List<User> list =response.getBody(); return list; } }
2 Consumer 的配置文件
spring.application.name=eureka-consumer server.port=9091 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
3 Provider 的集群部署
3.1将 provider 打包。部署到 linux 环境中
3.2创建启动脚本 server.sh
#!/bin/bash cd `dirname $0` CUR_SHELL_DIR=`pwd` CUR_SHELL_NAME=`basename ${BASH_SOURCE}` JAR_NAME="springcloud-eureka-provider-0.0.1-SNAPSHOT.jar" JAR_PATH=$CUR_SHELL_DIR/$JAR_NAME #JAVA_MEM_OPTS=" -server -Xms1024m -Xmx1024m -XX:PermSize=128m" JAVA_MEM_OPTS="" #SPRING_PROFILES_ACTIV="-Dspring.profiles.active=eureka2" SPRING_PROFILES_ACTIV="" LOG_DIR=$CUR_SHELL_DIR/logs LOG_PATH=$LOG_DIR/${JAR_NAME%..log echo_help() { echo -e "syntax: sh $CUR_SHELL_NAME start|stop" } if [ -z $1 ];then echo_help exit 1 fi if [ ! -d "$LOG_DIR" ];then mkdir "$LOG_DIR" fi if [ ! -f "$LOG_PATH" ];then touch "$LOG_DIR" fi if [ "$1" == "start" ];then # check server PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'` if [ -n "$PIDS" ]; then echo -e "ERROR: The $JAR_NAME already started and the PID is ${PIDS}." exit 1 fi echo "Starting the $JAR_NAME..." # start nohup java $JAVA_MEM_OPTS -jar $SPRING_PROFILES_ACTIV $JAR_PATH >> $LOG_PATH 2>&1 & COUNT=0 while [ $COUNT -lt 1 ]; do sleep 1 COUNT=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}' | wc -l` if [ $COUNT -gt 0 ]; then break fi done PIDS=`ps --no-heading -C java -f --width 1000 | grep "$JAR_NAME" | awk '{print $2}'` echo "${JAR_NAME} Started and the PID is ${PIDS}." echo "You can check the log file in ${LOG_PATH} for details." elif [ "$1" == "stop" ];then PIDS=`ps --no-heading -C java -f --width 1000 | grep $JAR_NAME | awk '{print $2}'` if [ -z "$PIDS" ]; then echo "ERROR:The $JAR_NAME does not started!" exit 1 fi echo -e "Stopping the $JAR_NAME..." for PID in $PIDS; do kill $PID > /dev/null 2>&1 done COUNT=0 while [ $COUNT -lt 1 ]; do sleep 1 COUNT=1 for PID in $PIDS ; do PID_EXIST=`ps --no-heading -p $PID` if [ -n "$PID_EXIST" ]; then COUNT=0 break fi done done echo -e "${JAR_NAME} Stopped and the PID is ${PIDS}." else echo_help exit 1 fi
4 启动 Consumer
四、 Ribbon 的常见负载均衡策略
五、 Ribbon 指定其他负载均衡策略
1 修改代码更换负载均衡策略
1.1创建项目
1.2在启动类中添加创建负载均衡策略对象的方法
@EnableEurekaClient @SpringBootApplication public class ConsumerApplication { 7 区域敏感性策略 ZoneAvoidanceRule: 1.以一个区域为单位考察可 用性,对于不可用的区域整个丢 弃,从剩下区域中选可用的 provider 2.如果这个 ip 区域内有一个或多 个实例不可达或响应变慢,都会降 低该 ip 区域内其他 ip 被选中的权 重。 @Bean public RandomRule createRule(){ return new RandomRule(); } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
2 修改配置文件更换负载均衡策略
#设置负载均衡策略 eureka-provider 为调用的服务的名称 eureka-provider.ribbon.NFLoadBalancerRuleClassName=com.netf lix.loadbalancer.RandomRule
六、 Ribbon 的点对点直连
2 去掉 Eureka 的坐标添加 Ribbon 坐标
<!-- ribbon 坐标 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
3 修改配置文件去掉与 Eureka 相关的配置,添加新配置项
spring.application.name=eureka-consumer-LB server.port=9091 #禁用 eureka ribbon.eureka.enabled=false #指定具体的服务实例清单 eureka-provider.ribbon.listOfServers=192.168.70.137:9090
4 修改启动类去掉报错代码
@SpringBootApplication public class ConsumerApplication { /*@Bean public RandomRule createRule(){ return new RandomRule(); }*/ public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
第二章 声明式服务调用 Feign
(Spring Cloud 高级)
一、 什么是 Feign
Feign 是一种声明式、模板化的 HTTP 客户端(仅在 consumer 中使用)。
二、 什么是声明式,有什么作用,解决什么问题?
声明式调用就像调用本地方法一样调用远程方法;无感知远程 http 请求。
1,Spring Cloud 的声明式调用, 可以做到使用 HTTP 请求远程服务时能就像调用本地
方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。
2,它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的
Http Client 构造请求再解析返回数据。
3,它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细
节,更无需关注分布式环境开发。
三、 编写 Feign 的入门案例
1 需求
实现 Ego 电商平台中的商品基本操作
2 项目设计
3 创建项目
3.1创建 Product-Service
3.1.1创建项目
3.1.2修改 pom 文件添加依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-service</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> </project>
3.1.3创建 Service 接口
/** * Product 服务接口 * @author Administrator * */ @RequestMapping("/product") public interface ProductService { //查询所有商品 @RequestMapping(value="/findAll",method=RequestMethod.GE T) public List<Product> findAll(); }
3.1.4创建 POJO 类
public class Product { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Product(Integer id, String name) { super(); this.id = id; this.name = name; } public Product() { super(); // TODO Auto-generated constructor stub } }
3.2创建 Product-Provider
3.2.1创建项目
3.2.2修改 pom 文件添加依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 添加 Feign 坐标 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- 添加 product-service 坐标 --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2.3添加全局配置文件
spring.application.name=ego-product-provider server.port=9001 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
3.2.4编写 Controller
/** * Product-Provider 服务 * @author Administrator * */ @RestController public class ProductController implements ProductService { @Override public List<Product> findAll() { List<Product> list = new ArrayList<>(); list.add(new Product(1, "电视")); list.add(new Product(2, "电脑")); list.add(new Product(3, "冰箱")); list.add(new Product(4, "手电筒")); return list; } }
3.2.5编写 SpringBoot 的启动类
@EnableEurekaClient @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
3.3创建 Product-consumer
3.3.1创建项目
3.3.2修改 pom 文件添加依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 添加 Feign 坐标 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- 添加 product-service 坐标 --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.3.3添加全局配置文件
spring.application.name=ego-product-consumer server.port=9002 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
3.3.4编写 Controller
/** * Product Consumer 服务 * @author Administrator * */ @RestController public class ProductController { @Autowired ProductConsumerService consumerservice; /** * Consumer 中的查询所有商品的方法 * @return */ @RequestMapping(value="/list",method=RequestMethod.GET) public List<Product> getAll(){ return this.consumerservice.findAll(); } }
3.3.5编写 Service 接口
@FeignClient(name="ego-product-provider") public interface ProductConsumerService extends ProductService{ }
3.3.6编写 SpringBoot 启动类
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
四、 Feign 的请求参数处理
1 单个参数处理
1.1修改 Product-Service
/** * Product 服务接口 * @author Administrator * */ @RequestMapping("/product") public interface ProductService { //查询所有商品 @RequestMapping(value="/findAll",method=RequestMethod.GE T) public List<Product> findAll(); //根据商品 ID 查询商品 @RequestMapping(value="/getProductById",method=RequestMe thod.GET) public Product getProductById(@RequestParam("id") Integer id); }
1.2修改 Product-Provider
/** * Product-Provider 服务 * @author Administrator * */ @RestController public class ProductController implements ProductService { @Override public List<Product> findAll() { List<Product> list = new ArrayList<>(); list.add(new Product(1, "电视")); list.add(new Product(2, "电脑")); list.add(new Product(3, "冰箱")); list.add(new Product(4, "手电筒")); return list; } @Override public Product getProductById(Integer id) { return new Product(id, "SpringCloud"); } }
1.3修改 Product-Consumer
/** * Product Consumer 服务 * @author Administrator * */ @RestController public class ProductController { @Autowired ProductConsumerService consumerservice; /** * Consumer 中的查询所有商品的方法 * @return */ @RequestMapping(value="/list",method=RequestMethod.GET) public List<Product> getAll(){ return this.consumerservice.findAll(); } /** * Consumer 中根据商品 id 查询商品 */ @RequestMapping(value="/get",method=RequestMethod.GET) public Product getProduct(@RequestParam("id") Integer id){ return this.consumerservice.getProductById(id); } }
2 多个参数处理
2.1方式一 GET 提交方式
2.1.1修改 Product-Service
/** * Product 服务接口 * @author Administrator * */ @RequestMapping("/product") public interface ProductService { //查询所有商品 @RequestMapping(value="/findAll",method=RequestMethod.GE T) public List<Product> findAll(); //根据商品 ID 查询商品 @RequestMapping(value="/getProductById",method=RequestMe thod.GET) public Product getProductById(@RequestParam("id") Integer id); //添加商品传递多个参数 方式一 :GET 方式 @RequestMapping(value="/add",method=RequestMethod.GET) public Product addProduct(@RequestParam("id") Integer id,@RequestParam("name") String name); }
2.1.2修改 Product-Provider
/** * Product-Provider 服务 * @author Administrator * */ @RestController public class ProductController implements ProductService { @Override public List<Product> findAll() { List<Product> list = new ArrayList<>(); list.add(new Product(1, "电视")); list.add(new Product(2, "电脑")); list.add(new Product(3, "冰箱")); list.add(new Product(4, "手电筒")); return list; } @Override public Product getProductById(Integer id) { return new Product(id, "SpringCloud"); } @Override public Product addProduct(Integer id, String name) { return new Product(id, name); }
2.1.3修改 Product-Consumer
/** * Product Consumer 服务 * @author Administrator * */ @RestController public class ProductController { @Autowired ProductConsumerService consumerservice; /** * Consumer 中的查询所有商品的方法 * @return */ @RequestMapping(value="/list",method=RequestMethod.GET) public List<Product> getAll(){ return this.consumerservice.findAll(); } /** * Consumer 中根据商品 id 查询商品 */ @RequestMapping(value="/get",method=RequestMethod.GET) public Product getProduct(@RequestParam("id") Integer id){ return this.consumerservice.getProductById(id); } /** * 商品添加 传递多个参数。方式一:GET */ @RequestMapping(value="/add",method=RequestMethod.GET) public Product addProduct(Product product){ return this.consumerservice.addProduct(product.getId(), product.getName()); } }
2.2方式二 POST 提交方式
2.2.1修改 Product-Service
/** * Product 服务接口 * @author Administrator * */ @RequestMapping("/product") public interface ProductService { //查询所有商品 @RequestMapping(value="/findAll",method=RequestMethod.GE T) public List<Product> findAll(); //根据商品 ID 查询商品 @RequestMapping(value="/getProductById",method=RequestMe thod.GET) public Product getProductById(@RequestParam("id") Integer id); //添加商品传递多个参数 方式一 :GET 方式 @RequestMapping(value="/add",method=RequestMethod.GET) public Product addProduct(@RequestParam("id") Integer id,@RequestParam("name") String name); //添加商品传递多个参数 方式二 :POST 方式 @RequestMapping(value="/add",method=RequestMethod.POST) public Product addProduct2(@RequestBody Product product); }
2.2.2修改 Product-Provider
/** * Product-Provider 服务 * @author Administrator * */ @RestController public class ProductController implements ProductService { @Override public List<Product> findAll() { List<Product> list = new ArrayList<>(); list.add(new Product(1, "电视")); list.add(new Product(2, "电脑")); list.add(new Product(3, "冰箱")); list.add(new Product(4, "手电筒")); return list; } @Override public Product getProductById(Integer id) { return new Product(id, "SpringCloud"); } @Override public Product addProduct(Integer id, String name) { return new Product(id, name); } @Override public Product addProduct2(@RequestBody Product product) { return product; } }
2.2.3修改 Product-Consumer
/** * Product Consumer 服务 * @author Administrator * */ @RestController public class ProductController { @Autowired ProductConsumerService consumerservice; /** * Consumer 中的查询所有商品的方法 * @return */ @RequestMapping(value="/list",method=RequestMethod.GET) public List<Product> getAll(){ return this.consumerservice.findAll(); } /** * Consumer 中根据商品 id 查询商品 */ @RequestMapping(value="/get",method=RequestMethod.GET) public Product getProduct(@RequestParam("id") Integer id){ return this.consumerservice.getProductById(id); } /** * 商品添加 传递多个参数。方式一:GET */ @RequestMapping(value="/add",method=RequestMethod.GET) public Product addProduct(Product product){ return this.consumerservice.addProduct(product.getId(), product.getName()); } /** * 商品添加 传递多个参数。方式二:POST */ @RequestMapping(value="/add2",method=RequestMethod.GET) public Product addProduct2(Product product){ return this.consumerservice.addProduct2(product); } }
五、 Feign 的性能优化
1 通过 Gzip 压缩算法,提升网络通信速度
1.1gzip 介绍
gzip 介绍:gzip 是一种数据格式,采用用 deflate 算法压缩 data;gzip 是一种流行的文件
压缩算法,应用十分广泛,尤其是在 Linux 平台。
gzip 能力:当 Gzip 压缩到一个纯文本文件时,效果是非常明显的,大约可以减少 70%以上的文件大小。
gzip 作用:网络数据经过压缩后实际上降低了网络传输的字节数,最明显的好处就是可
以加快网页加载的速度。网页加载速度加快的好处不言而喻,除了节省流量,改善用户的浏
览体验外,另一个潜在的好处是 Gzip 与搜索引擎的抓取工具有着更好的关系。例如 Google
就可以通过直接读取 gzip 文件来比普通手工抓取 更快地检索网页。
1.2HTTP 协议中关于压缩传输的规定
第一:客户端向服务器请求中带有:Accept-Encoding:gzip, deflate 字段,向服务器表示,
客户端支持的压缩格式(gzip 或者 deflate),如果不发送该消息头,服务器是不会压缩的。
第二:服务端在收到请求之后,如果发现请求头中含有 Accept-Encoding 字段,并且支
持该类型的压缩,就对响应报文压缩之后返回给客户端,并且携带 Content-Encoding:gzip 消
息头,表示响应报文是根据该格式压缩过的。
第三:客户端接收到请求之后,先判断是否有 Content-Encoding 消息头,如果有,按该
格式解压报文。否则按正常报文处理。
2 编写支持 Gzip 压缩案例
2.2修改配置文件
2.2.1只配置 Consumer 通过 Feign 到 Provider 的请求与相应
的 Gzip 压缩
#-----------------------------feign gzip #配置请求 GZIP 压缩 feign.compression.request.enabled=true #配置响应 GZIP 压缩 feign.compression.response.enabled=true #配置压缩支持的 MIME TYPE feign.compression.request.mime-types=text/xml,application/x ml,application/json #配置压缩数据大小的最小阀值,默认 2048 feign.compression.request.min-request-size=512
2.2.2对客户端浏览器的请求以及 Consumer 对 provider 的请
求与响应做 Gzip 压缩
#-----------------------------spring boot gzip #是否启用压缩 server.compression.enabled=true server.compression.mime-types=application/json,application/ xml,text/html,text/xml,text/plain
3 采用 Http 连接池,提升 Feign 的并发吞吐量
为什么 http 连接池能提升性能?
3.1http 的背景原理
a. 两台服务器建立 http 连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并
且也很耗时间。
b. Http 连接需要的 3 次握手 4 次分手开销很大,这一开销对于大量的比较小的 http 消
息来说更大。
3.2优化解决方案
a. 如果我们直接采用 http 连接池,节约了大量的 3 次握手 4 次分手;这样能大大提升吞
吐率。
b. feign 的 http 客户端支持 3 种框架;HttpURLConnection、httpclient、okhttp;默认是
HttpURLConnection。
c. 传统的 HttpURLConnection 是 JDK 自带的,并不支持连接池,如果要实现连接池的
机制,还需要自己来管理连接对象。对于网络请求这种底层相对复杂的操作,如果有可用的
其他方案,也没有必要自己去管理连接对象。
d. HttpClient 相比传统 JDK 自带的 HttpURLConnection,它封装了访问 http 的请求头,
参数,内容体,响应等等;它不仅使客户端发送 HTTP 请求变得容易,而且也方便了开发人
员测试接口(基于 Http 协议的),即提高了开发的效率,也方便提高代码的健壮性;另外
高并发大量的请求网络的时候,还是用“连接池”提升吞吐量
4 将 Feign 的 Http 客户端工具修改为 HttpClient
4.1创建项目
4.2修改 pom 文件添加 HttpClient 的坐标
<!-- 使用Apache HttpClient替换Feign原生httpURLConnection -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> </dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>8.17.0</version> </dependency>
4.3修改配置文件开启 HttpClient 的使用
#启用 httpclient
feign.httpclient.enabled=true
注意:如果使用 HttpClient 作为 Feign 的客户端工具。那么在定义接口上的注解是需要
注意,如果传递的是一个自定义的对象(对象会使用 json 格式来专递)。需要制定类型。
4.4Product-Service
/** * Product 服务接口* @author Administrator * */ @RequestMapping("/product") public interface ProductService { //查询所有商品 @RequestMapping(value="/findAll",method=RequestMethod.GE T) public List<Product> findAll(); //根据商品 ID 查询商品 @RequestMapping(value="/getProductById",method=RequestMe thod.GET) public Product getProductById(@RequestParam("id") Integer id); //添加商品传递多个参数 方式一 :GET 方式 @RequestMapping(value="/add",method=RequestMethod.GET) public Product addProduct(@RequestParam("id") Integer id,@RequestParam("name") String name); //----------------------Httpclient---------------------- ------------------------ //添加商品传递多个参数 方式二 :POST 方式 @RequestMapping(value="/add2",method=RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE) public Product addProduct2(@RequestBody Product product); //使用 HttpClient 工具 添加商品传递多个参数 :基于 GET 方式 @RequestMapping(value="/add3",method=RequestMethod.GET,c onsumes=MediaType.APPLICATION_JSON_VALUE) public Product addProduct3(Product product); }
六、 查看微服务日志中记录每个接口 URL,状态码和耗时信息
1 创建项目
2 添加 logback.xml 文件
3 Logback 的输出日志级别需要时 debug 级别
<!-- 日志输出级别 --> <root level="DEBUG"> <appender-ref ref="Stdout" /> <appender-ref ref="RollingFile" /> </root>
4 在启动类中添加一个方法
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class ConsumerApplication { // NONE:不记录任何信息,默认值 // BASIC:记录请求方法、请求 URL、状态码和用时 // HEADERS:在 BASIC 基础上再记录一些常用信息 // FULL:记录请求和相应的所有信息 @Bean public Logger.Level getLog(){ return Logger.Level.FULL; } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
七、 配置 Feign 负载均衡请求超时时间
Feign 的负载均衡底层用的就是 Ribbon
1 修改配置文件,设置超时时间
consumer里面配置
1.1全局配置
#全局配置 # 请求连接的超时时间 默认的时间为 1 秒 ribbon.ConnectTimeout=5000 # 请求处理的超时时间 ribbon.ReadTimeout=5000
1.2根据服务名称进行局部超时配置
#局部配置 # 对所有操作请求都进行重试 ego-product-provider.ribbon.OkToRetryOnAllOperations=true # 对当前实例的重试次数 ego-product-provider.ribbon.MaxAutoRetries=2 # 切换实例的重试次数 ego-product-providert.ribbon.MaxAutoRetriesNextServer=0 # 请求连接的超时时间 ego-product-provider.ribbon.ConnectTimeout=3000 # 请求处理的超时时间 ego-product-provider.ribbon.ReadTimeout=3000
第三章 Hystrix服务容错保护
1.2修改 pom 文件添加 hystrix 的坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
1.3修改配置文件
spring.application.name=eureka-consumer-ribbon-hystrix server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
1.4修改启动类开启熔断器
@EnableCircuitBreaker //开启熔断器 断路器 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
1.5在项目中添加 Product 实体类
public class Product { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Product(Integer id, String name) { super(); this.id = id; this.name = name; } public Product() { super(); // TODO Auto-generated constructor stub } }
1.6修改 ProductService
@Service public class ProductService { @Autowired private LoadBalancerClient loadBalancerClient;// ribbon 负 载均衡器 @HystrixCommand(fallbackMethod="fallback") public List<Product> getUsers() { // 选择调用的服务的名称 // ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider"); // 拼接访问服务的 URL StringBuffer sb = new StringBuffer(); // http://localhost:9001/product/findAll sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/product/findAll"); System.out.println(sb.toString()); // springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() { }; // ResponseEntity:封装了返回值信息 ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); List<Product> list = response.getBody(); return list; } //返回托底数据的方法 public List<Product> fallback(){ List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; }}
1.7以下四种情况将触发 getFallback 调用
(1) 方法抛出非 HystrixBadRequestException 异常。
(2) 方法调用超时
(3) 熔断器开启拦截调用
(4) 线程池/队列/信号量是否跑满
2 请求缓存
Hystrix 为了降低访问服务的频率,支持将一个请求与返回结果做缓存处理。如果再次
请求的 URL 没有变化,那么 Hystrix 不会请求服务,而是直接从缓存中将结果返回。这样可
以大大降低访问服务的压力。
Hystrix 自带缓存。有两个缺点:
1. 是一个本地缓存。在集群情况下缓存是不能同步的。
2. 不支持第三方缓存容器。Redis,memcache 不支持的。
可以使用 spring 的 cache。
2.1安装 Redis
2.2创建项目
2.3修改 pom 文件添加 springCache 坐标
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-ribbon-cache</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <!-- springCache --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.4在配置文件中配置 redis 链接信息
spring.application.name=eureka-consumer-ribbon-cache server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/ # Redis spring.redis.database=0 #Redis 服务器地址 spring.redis.host=192.168.70.139 #Redis 服务器连接端口 spring.redis.port=6379 #Redis 服务器连接密码(默认为空) spring.redis.password= #连接池最大连接数(负值表示没有限制) spring.redis.pool.max-active=100 #连接池最大阻塞等待时间(负值表示没有限制) spring.redis.pool.max-wait=3000 #连接池最大空闭连接数 spring.redis.pool.max-idle=200 #连接汉最小空闲连接数 spring.redis.pool.min-idle=50 #连接超时时间(毫秒) spring.redis.pool.timeout=600
2.5修改启动类开启缓存
@EnableCaching @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
2.6修改 ProductService
@CacheConfig(cacheNames={"com.bjsxt.ego.product"}) @Service public class ProductService { @Autowired private LoadBalancerClient loadBalancerClient;// ribbon 负 载均衡器 @HystrixCommand(fallbackMethod="fallback") public List<Product> getUsers() { // 选择调用的服务的名称 // ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider"); // 拼接访问服务的 URL StringBuffer sb = new StringBuffer(); // http://localhost:9001/product/findAll sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/product/findAll"); System.out.println(sb.toString()); // springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() { }; // ResponseEntity:封装了返回值信息 ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); List<Product> list = response.getBody(); return list; } //返回托底数据的方法 public List<Product> fallback(){ List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; } //根据 ID 查询商品 @Cacheable(key="'product' + #id") public Product getProductById(Integer id){ System.out.println("=========Get======"+id); return new Product(id, "新的商品"); } //根据 ID 删除商品 @CacheEvict(key="'product' + #id") public void delProductById(Integer id){ System.out.println("=========Del======"+id); } }
2.7修改 ProductController
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer") public List<Product> getUsers() { return this.userService.getUsers(); } @RequestMapping(value="/get",method=RequestMethod.GET) public Product get(Integer id){ return this.userService.getProductById(id); } @RequestMapping(value="/del",method=RequestMethod.GET) public void del(Integer id){ this.userService.delProductById(id); } }
3 请求合并
没合并的请求
请求合并
3.2修改 pom 文件添加 hystrix 坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
3.3修改配置文件
spring.application.name=eureka-consumer-ribbon-batch server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
3.4修改 ProductService
@Service public class ProductService { //利用 hystrix 合并请求 @HystrixCollapser(batchMethod = "batchProduct", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL, collapserProperties = { //请求时间间隔在 20ms 之内的请求会被合并为一个请求,默认 为 10ms @HystrixProperty(name = "timerDelayInMilliseconds", value = "20"), //设置触发批处理执行之前,在批处理中允许的最大请求 数。 @HystrixProperty(name = "maxRequestsInBatch", value = "200"), }) //consumer 的 controller 调用的方法 该方法返回值必须要返回 Future 类型 public Future<Product> getProduct(Integer id){ System.out.println("=========="+id+"=========="); return null; } @HystrixCommand //调用 Provider 服务的方法 public List<Product> batchProduct(List<Integer> ids){ for(Integer id:ids){ System.out.println(id); } //假设是调用 provider 服务后返回的 list List<Product> list = new ArrayList<>(); list.add(new Product(1, "电视")); list.add(new Product(2, "电脑")); list.add(new Product(3, "冰箱")); list.add(new Product(4, "手电筒")); list.add(new Product(100,"list............")); System.out.println("ddddddddddddddddddddddd"); return list; } }
3.5修改 Controller
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer")public void getUsers() throws Exception{ Future<Product> p1 = this.userService.getProduct(1); Future<Product> p2 = this.userService.getProduct(2); Future<Product> p3 = this.userService.getProduct(3); System.out.println(p1.get().toString()); System.out.println(p2.get().toString()); System.out.println(p3.get().toString()); } }
4 服务熔断
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
4.3修改配置文件
spring.application.name=eureka-consumer-ribbon-breaker server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
4.4修改启动类
@EnableCircuitBreaker //开启熔断器 断路器 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
4.5修改 ProductService
@Service public class ProductService { @Autowired private LoadBalancerClient loadBalancerClient;// ribbon 负 载均衡器 @HystrixCommand(fallbackMethod = "fallback", commandProperties = { //默认 20 个;10s 内请求数大于 20 个时就启动熔断器,当请 求符合熔断条件时将触发 getFallback()。 @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER _REQUEST_VOLUME_THRESHOLD, value="10"), //请求错误率大于 50%时就熔断,然后 for 循环发起请求, 当请求符合熔断条件时将触发 getFallback()。 @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER _ERROR_THRESHOLD_PERCENTAGE, value="50"), //默认 5 秒;熔断多少秒后去尝试请求 @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER _SLEEP_WINDOW_IN_MILLISECONDS, value="5000"), }) public List<Product> getUsers(int flag) { System.out.println(flag); if(flag == 1){ throw new RuntimeException(); } // 选择调用的服务的名称 // ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider"); // 拼接访问服务的 URL StringBuffer sb = new StringBuffer(); // http://localhost:9001/product/findAll sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/product/findAll"); System.out.println(sb.toString()); // springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() { }; // ResponseEntity:封装了返回值信息 ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); List<Product> list = response.getBody(); return list; } //返回托底数据的方法 public List<Product> fallback(int flag){ List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; } }
4.6修改 ProductController
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer") public List<Product> getUsers(@RequestParam("flag") Integer flag){ return this.userService.getUsers(flag); } }
5.1.2修改 pom 添加 hystrix 坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
5.1.3修改配置文件
spring.application.name=eureka-consumer-ribbon-threadpool server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
5.1.4修改启动类
@EnableCircuitBreaker //开启熔断器 断路器 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
5.1.5修改 ProductService
package com.hainei.netty_test.test.jvm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; @Service public class ProductService { @Autowired private LoadBalancerClient loadBalancerClient; // ribbon 负载均衡器 @HystrixCommand(groupKey="ego-product-provider", commandKey = "getUsers", threadPoolKey="ego-product-provider", threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "30"),//线程池大小 @HystrixProperty(name = "maxQueueSize", value = "100"),//最大队列长度 @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),//线程存活时间 @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15")//拒绝请求 }, fallbackMethod = "fallback") public List<Product> getUsers() { System.out.println(Thread.currentThread().getName()); // 选择调用的服务的名称 // ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider"); // 拼接访问服务的 URL StringBuffer sb = new StringBuffer(); // http://localhost:9001/product/findAll sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/product/findAll"); System.out.println(sb.toString()); // springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {}; // ResponseEntity:封装了返回值信息 ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); List<Product> list = response.getBody(); return list; } //返回托底数据的方法 public List<Product> fallback(){ System.out.println(Thread.currentThread().getName()); List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; } public void showThread(){ System.out.println(Thread.currentThread().getName()); } }
5.1.6修改 ProductController
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer") public List<Product> getUsers(){ return this.userService.getUsers(); } @RequestMapping("/consumer1") public void getUsers1(){ this.userService.showThread(); } }
5.2.2修改 pom 文件添加 hystrix 的坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
5.2.3修改配置文件
spring.application.name=eureka-consumer-ribbon-semaphore server.port=9010 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
5.2.5修改 ProductService
@Service public class ProductService { @Autowired private LoadBalancerClient loadBalancerClient;// ribbon 负 载均衡器 @HystrixCommand(fallbackMethod = "fallback", commandProperties = { @HystrixProperty(name=HystrixPropertiesManager.EXECUTION_ISOLA TION_STRATEGY, value="SEMAPHORE"),// 信号量 隔离 @HystrixProperty (name=HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHOR E_MAX_CONCURRENT_REQUESTS, value="100")//信号量最大并度 }) public List<Product> getUsers() { System.out.println(Thread.currentThread().getName()); // 选择调用的服务的名称 // ServiceInstance 封装了服务的基本信息,如 IP,端口 ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider"); // 拼接访问服务的 URL StringBuffer sb = new StringBuffer(); // http://localhost:9001/product/findAll sb.append("http://").append(si.getHost()).append(":").appen d(si.getPort()).append("/product/findAll"); System.out.println(sb.toString()); // springMVC RestTemplate RestTemplate rt = new RestTemplate(); ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() { }; // ResponseEntity:封装了返回值信息 ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); List<Product> list = response.getBody(); return list; } //返回托底数据的方法 public List<Product> fallback(){ System.out.println(Thread.currentThread().getName()); List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; } public void showThread(){ System.out.println(Thread.currentThread().getName()); } }
1.2修改配置文件开启对 hystrix 的支持
@Component public class ProductServiceFallbackFactory implements FallbackFactory<ProductConsumerService> { Logger logger = LoggerFactory.getLogger(ProductServiceFallbackFactory.class); @Override public ProductConsumerService create(final Throwable arg0) { return new ProductConsumerService() { //能够返回托底数据的 fallback 方法 @Override public List<Product> findAll() { logger.warn("Fallback Exception: ",arg0); List<Product> list = new ArrayList<>(); list.add(new Product(-1, "我是托底数据")); return list; } }; } }
2.3修改 ProductConsumerService
@FeignClient(name="ego-product-provider",fallbackFactory=Pr oductServiceFallbackFactory.class) public interface ProductConsumerService { //查询所有商品 @RequestMapping(value="/product/findAll",method=RequestMeth od.GET) public List<Product> findAll(); }
五、 可视化的数据监控 Hystrix-dashboard
Hystrix-dashboard 是一款针对 Hystrix 进行实时监控的工具,通过 Hystrix
Dashboard 我们可以在直观地看到各 Hystrix Command 的请求响应时间, 请求成功率等数据。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-ribbon-dashboard </artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEn coding> <project.reporting.outputEncoding>UTF-8</project.reporting. outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId > </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.修改启动类
@EnableCircuitBreaker //开启熔断器 断路器 @EnableEurekaClient @SpringBootApplication @EnableHystrix @EnableHystrixDashboard public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-ribbon-dashboard</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId > </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
4.3修改启动类
@EnableCircuitBreaker //开启熔断器 断路器 @EnableEurekaClient @SpringBootApplication @EnableHystrix @EnableHystrixDashboard public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
1.1修改 pom 文件添加 turbine 坐标
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-turbine</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId > </dependency> <!-- 添加 turbine 坐标 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-turbine</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.2修改配置文件
spring.application.name=eureka-consumer-hystrix-turbine server.port=1002 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/ #---------------------------------------turbine------------ -------------- #配置 Eureka 中的 serviceId 列表,表明监控哪些服务 turbine.appConfig=eureka-consumer-ribbon-threadpool,springc loud-eureka-consumer-feign-fallback #指定聚合哪些集群,多个使用","分割,默认为 default。可使用 http://.../turbine.stream?cluster={clusterConfig 之一}访问 turbine.aggregator.clusterConfig= default # 1. clusterNameExpression 指定集群名称,默认表达式 appName;此 时:turbine.aggregator.clusterConfig 需要配置想要监控的应用名称; # 2. 当 clusterNameExpression: default 时, turbine.aggregator.clusterConfig 可以不写,因为默认就是 default; # 3. 当 clusterNameExpression: metadata['cluster']时,假设想要 监控的应用配置了 eureka.instance.metadata-map.cluster: ABC, # 则需要配置,同时 turbine.aggregator.clusterConfig: ABC turbine.clusterNameExpression="default"
1.3修改启动类
@SpringBootApplication @EnableTurbine public class HystrixTurbineApplication { public static void main(String[] args) { SpringApplication.run(HystrixTurbineApplication.class, args); } }
2 使用 Turbine 聚合多个服务
2.1修改被聚合的项目的 pom 文件添加 dashboard 坐标
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-feign-fallback</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 添加 Feign 坐标 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- 添加 product-service 坐标 --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>springcloud-ego-product-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId > </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.2修改被监控的服务的启动类
@EnableFeignClients @EnableDiscoveryClient @SpringBootApplication @EnableHystrixDashboard @EnableCircuitBreaker //开启熔断器 断路器 public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
http://localhost:1002/turbine.stream
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-ribbon-dashboard-mq</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-hystrix-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>springcloud-eureka-consumer-turbine-mq</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-eureka-consumer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
7 修改 Turbine 的配置文件
spring.application.name=eureka-consumer-hystrix-turbine server.port=1002 #设置服务注册中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http://user:123456@eur eka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/ spring.rabbitmq.host=192.168.70.139 spring.rabbitmq.port=5672 spring.rabbitmq.username=oldlu spring.rabbitmq.password=123456 spring.rabbitmq.virtualHost=/
8 修改 Turbine 的启动类
@SpringBootApplication @EnableTurbineStream public class HystrixTurbineApplication { public static void main(String[] args) { SpringApplication.run(HystrixTurbineApplication.class, args); } }
zipkin-producer
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>org.example</groupId> <artifactId>zipkin-producer-test2</artifactId> <version>1.0-SNAPSHOT</version> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.RC2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> </dependency> <!-- sleuth配置 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <!-- 引入zipkin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.5</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk16</artifactId> <version>1.46</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.41</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> </dependency> <dependency> <groupId>org.influxdb</groupId> <artifactId>influxdb-java</artifactId> <version>2.15</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.12.0</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
zipkin-consumer
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.hps</groupId> <artifactId>zipkin-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>zipkin-consumer</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.RC2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> </dependency> <!-- sleuth配置 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <!-- 引入zipkin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-core</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
1111
个人学习笔记,记录日常学习,便于查阅及加深,仅为方便个人使用。