SpringCloud定制小程序开发无介绍快使用,定制小程序开发负载均衡工具与OpenFeign的使用(十五)
问题背景
定制小程序开发从零开始学springcloud定制小程序开发微服务项目
注意事项:
- 约定 > 配置 > 编码
- IDEA版本2021.1
- 这个项目,定制小程序开发我分了很多篇章,定制小程序开发每篇文章一个操作步骤,定制小程序开发目的是显得更简单明了
- controller调service,service调dao
Ribbon负载均衡
1 Spring Cloud Ribbon是基于 Ribbon定制小程序开发实现的一套客户端负载均衡的工具
- Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用
- Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等
- 在配置文件中列出LoadBalancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法
2 集中式LB
- 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方
3 进程内LB
- 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后再从这些地址中选择出一个合适的服务器
- Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址
4 Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别
- Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的
- Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术
5 Ribbon在工作时分成两步
- 第一步先选择 EurekaServer ,它优先选择在同一个区域内负载较少的server
- 第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权
- Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例
6 前面几个篇章就是使用了Ribbon负载均衡,RestTemplate+@LoadBalanced实现负载均衡,使用依赖包含在Eureka-client中
<!--eureka-client--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
- 1
- 2
- 3
- 4
- 5
默认使用Ribbon做负载均衡
1 OpenFeign集成了Ribbon
- 利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
2 新增module
3 选择jdk1.8
4 输入服务名:cloud-consumer-feign-order80
5 复制cloud-consumer-order80到cloud-consumer-feign-order80
更改pom依赖
<?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"> <parent> <artifactId>springcloud2022</artifactId> <groupId>com.yg</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumer-feign-order80</artifactId> <dependencies> <!--openfeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --> <groupId>com.yg</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies></project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
更改application文件,添加超时连接控制和日志增强
server: port: 80spring: application: name: cloud-consumer-ordereureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka instance: instance-id: order80 prefer-ip-address: true #访问路径可以显示IP地址#设置feign客户端超时时间(OpenFeign默认支持ribbon)ribbon: #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间 ReadTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用的时间 ConnectTimeout: 5000logging: level: # feign日志以什么级别监控哪个接口 com.yg.springcloud.service.PaymentFeignService: debug
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
更改启动类
package com.yg.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;/** * @Author suolong * @Date 2022/6/15 15:10 * @Version 2.0 */@EnableEurekaClient@EnableFeignClients@SpringBootApplicationpublic class FeignMainApp80 { public static void main(String[] args) { SpringApplication.run(FeignMainApp80.class); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
添加openFeign的日志打印配置
package com.yg.springcloud.config;import feign.Logger;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;/** * @Author suolong * @Date 2022/6/15 20:53 * @Version 2.0 */@Configurationpublic class ApplicationContextConfig { @Bean @LoadBalanced // 使用@LoadBalanced注解赋予RestTemplate负载均衡的能力 public RestTemplate restTemplate() { return new RestTemplate(); } @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
更改controller
package com.yg.springcloud.controller;import com.yg.springcloud.entities.CommonResult;import com.yg.springcloud.entities.Payment;import com.yg.springcloud.service.PaymentFeignService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/** * @Author suolong * @Date 2022/6/15 20:54 * @Version 2.0 */@RestControllerpublic class OrderController { //public static final String PaymentSrv_URL = "http://localhost:8001"; public static final String PaymentSrv_URL = "http://CLOUD-PAYMENT-SERVICE"; @Autowired private RestTemplate restTemplate; @Resource private PaymentFeignService paymentFeignService; @GetMapping(value = "/consumer/feign/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) { return paymentFeignService.getPaymentById(id); } @GetMapping("/consumer/payment/create") //客户端用浏览器是get请求,但是底层实质发送post调用服务端8001 public CommonResult create(Payment payment) { return restTemplate.postForObject(PaymentSrv_URL + "/payment/create", payment, CommonResult.class); } @GetMapping("/consumer/payment/get/{id}") public CommonResult getPayment(@PathVariable Long id) { return restTemplate.getForObject(PaymentSrv_URL + "/payment/get/" + id, CommonResult.class, id); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
添加feign调用
package com.yg.springcloud.service;import com.yg.springcloud.entities.CommonResult;import com.yg.springcloud.entities.Payment;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.stereotype.Component;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;/** * @Author suolong * @Date 2022/6/19 15:06 * @Version 2.0 */@Component@FeignClient(value = "cloud-payment-service")public interface PaymentFeignService { @GetMapping(value = "/payment/get/{id}") CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
6 整体目录结构
7 postman测试:http://localhost/consumer/feign/get/1
- 8001和8002服务器交替出现,说明openfeign自带ribbon负载均衡
- 消费方也打印详细feign调用的日志
2022-06-19 15:25:02.356 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] ---> GET http://cloud-payment-service/payment/get/1 HTTP/1.12022-06-19 15:25:02.356 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] ---> END HTTP (0-byte body)2022-06-19 15:25:02.469 INFO 34144 --- [p-nio-80-exec-2] c.netflix.config.ChainedDynamicProperty : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 21474836472022-06-19 15:25:02.496 INFO 34144 --- [p-nio-80-exec-2] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-cloud-payment-service2022-06-19 15:25:02.496 INFO 34144 --- [p-nio-80-exec-2] c.netflix.loadbalancer.BaseLoadBalancer : Client: cloud-payment-service instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=cloud-payment-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null2022-06-19 15:25:02.501 INFO 34144 --- [p-nio-80-exec-2] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater2022-06-19 15:25:02.518 INFO 34144 --- [p-nio-80-exec-2] c.netflix.config.ChainedDynamicProperty : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 21474836472022-06-19 15:25:02.518 INFO 34144 --- [p-nio-80-exec-2] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client cloud-payment-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=cloud-payment-service,current list of Servers=[10.2.0.85:8001, 10.2.0.85:8002],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:2; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]},Server stats: [[Server:10.2.0.85:8002; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0], [Server:10.2.0.85:8001; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@27468f172022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] <--- HTTP/1.1 200 (219ms)2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] connection: keep-alive2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] content-type: application/json2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] date: Sun, 19 Jun 2022 07:25:02 GMT2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] keep-alive: timeout=602022-06-19 15:25:02.576 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] transfer-encoding: chunked2022-06-19 15:25:02.576 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] 2022-06-19 15:25:02.577 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] {"code":200,"message":"查询成功哈: 8001","data":{"id":1,"serial":"abc"}}2022-06-19 15:25:02.577 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService : [PaymentFeignService#getPaymentById] <--- END HTTP (77-byte body)2022-06-19 15:25:03.519 INFO 34144 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
作为程序员第 182 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …