Spring Cloud

微服务概念

微服务组件示意图

image-20211019105136125

核心问题

  • 服务很多客户端怎么访问
  • 这么多服务如何通信
  • 如何治理
  • 服务崩溃怎么解决

注册中心

介绍

介你麻痹

学习顺序

image-20211019153453227

CAP原则

image-20211021110645846

A 可用性、C 一致性、P 分布式

  • Availability 可用性

  • Partition-Tolerance 分区容错性

  • Consistency 一致性

CP 效率低(牺牲可用性)

AP 牺牲一致性 (有脏数据)

CA 牺牲横向可扩容

对比

image-20211019154311484

Eureka

架构原理

image-20211021010435143

image-20211021110609551

  • 注册中心 Eureka Server
    • 之间相互同步 Replicate
  • 应用服务
    • 注册 Registry
    • 定时心跳机制 Renew
    • 下线 Cancel
    • 获取其他微服务信息 Get Registry
  • 客户端服务 Client
    • Get Registry
    • Make Remote Call

角色

image-20211019155118165

  • Server 注册中心
  • Service Provider 服务提供者
    • 注册、重新注册、清除 Register/Renew/Cancel
  • Servcie Consumer 服务消费者
    • 负载均衡的调用 Remote Call
    • 拉取服务地址 Get Registery

调用顺序

image-20211019155703868

搭建入门

需求
搭建文档要到官方照xml

从官方找到maven依赖

建立eureka demo项目和eureka server 模块

参考文档:

spring eureka:https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/

maven :https://mvnrepository.com/search?q=spring+cloud+eureka+netflix

  • demo maven pom.xml

    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
    <?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>org.akachi</groupId>
    <artifactId>eurekademo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
    <module>server</module>
    </modules>

    <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <spring.cloud-version>Hoxton.SR8</spring.cloud-version>
    </properties>

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.5</version>
    </parent>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</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>
    </project>
  • eureka server pom.xml

    创建一个基础eureka demo 的server 选择spring boot Web 、 Spring Cloud starter eureka server

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.akachi</groupId>
    <artifactId>eurekademo</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>server</name>
    <description>Demo project for Spring Boot</description>
    <properties>
    <java.version>11</java.version>
    <spring-cloud.version>2020.0.4</spring-cloud.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <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-server</artifactId>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    </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>
    <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>

    </project>

  • application.yml 配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    server:
    port: ${SERVICE_PORT:8761}
    spring:
    jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    show-sql: true
    hibernate:
    naming:
    physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    application:
    name: eurekademo-server
    datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://localhost:4306/eurekademo
    eureka:
    instance:
    hostname: localhost
    client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
    defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    参考资料:https://docs.spring.io/spring-cloud-netflix/docs/3.0.3/reference/html/#netflix-eureka-client-starter

    image-20211019230320276

单节点环境下 register-with-eureka: false

​ fetch-registry: false

自己不要给自己注册。会报错

通过 http://${eureka.instance.hostname}:${server.port}/eureka/ 能够访问到eureka

需要在EurekaServerApplication类头上添加一个注解 @EanbleEurekaServer

image-20211019232157998

看到这个界面入门案例久搭建成功了

搭建集群版的注册中心

要注意我再这里用了Run/Debug Configuration 来启动多个相互注册的eureka而不是建立多个项目。

需要服务注册中心相互注册所以需要从新配置

18761>18762>18763

修改内容包含

1
2
3
4
register-with-eureka: true # 将自己注册到注册中心 默认 true
fetch-registry: true # 是否从注册中心获取服务注册信息 默认true
hostname:
port:等等

yml

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
server:
port: ${SERVICE_PORT:8761}
spring:
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# ddl-auto: update
application:
name: eurekademo-server
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:4306/eurekademo
eureka:
instance:
hostname: ${INSTANCE_HOSTNAME:eureka01}
prefer-ip-address: true
server:
port: ${EUREKA_SERVER_PORT:8761}
hostname: ${EUREKA_SERVER_NAME:localhost}
client:
register-with-eureka: true # 将自己注册到注册中心 默认 true
fetch-registry: true # 是否从注册中心获取服务注册信息 默认true
service-url:
defaultZone: http://${eureka.server.hostname}:${eureka.server.port}/eureka/
ip+端口作为名字注册

加入配置

1
2
3
4
5
6
7
8
9
10
eureka:
instance:
hostname: ${INSTANCE_HOSTNAME:eureka01}
prefer-ip-address: true
# 这种情况下需要配合一系列的配置使计算机获得正确的服务
cloud:
inetutils:
ignoredInterfaces: ['VMware.*','ingress']
preferred-networks:
- ${NET_DOMAIN:192.168/16}

也可以无视继续使用

开发一个 provider

  • pom.xml
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.akachi</groupId>
<artifactId>eurekademo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>org.akachi.eurekademo</groupId>
<artifactId>product</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<spring-boot.version>2.5.5</spring-boot.version>
<netflix-eureka-server.version>3.0.4</netflix-eureka-server.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>${netflix-eureka-server.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>8.0.26</version>
</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>
<version>${spring-boot.version}</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>
</plugins>
</build>
</project>

  • yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server:
port: ${SERVICE_PORT:18180}
spring:
application:
name: eurekademo-service-product
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:4306/eurekademo
eureka:
client:
register-with-eureka: true # 将自己注册到注册中心 默认 true
fetch-registry: true # 是否从注册中心获取服务注册信息 默认true
service-url:
defaultZone: http://localhost:18761/eureka/,http://localhost:18762/eureka/,http://localhost:18763/eureka/
  • 开发一个商品接口

问题:

  1. 不是所有的eureka集群上都有服务
  2. eureka会出现自我保护机制的红字
eureka的保护机制

eureka是通过renew、心跳包进行连接的。

90秒也就是3次没有收到心跳包就会剔除掉微服务。

eureka有可能会怀疑自己的网络出现故障,会提示自己可能出现网络问题。

image-20211021132008463

就是说在所有服务中有25%的服务无法连接eureka就会认为可能是自己网络出现问题。需要我们去手动排查网络并且,他会保留微服务。

可以在配置文件中关闭自我保护

1
2
3
4
eureka:
server:
enable-self-preservation: true
eviction-interval-timer-in-ms: 60000

开发一个 consumer

yml

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
server:
port: ${SERVICE_PORT:18280}
spring:
application:
name: eurekademo-service-order
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:4306/eurekademo
eureka:
client:
register-with-eureka: false # 将自己注册到注册中心 默认 true
fetch-registry: true # 是否从注册中心获取服务注册信息 默认true
service-url:
defaultZone: http://localhost:18761/eureka/,http://localhost:18762/eureka/,http://localhost:18763/eureka/
registry-fetch-interval-seconds: 10 # 表示 eureka Client 间隔多久去服务器拉取注册信息,默认为 30 秒。

大体配置与product相同,注意

1
2
3
4
5
eureka:
client:
register-with-eureka: false # 将自己注册到注册中心 默认 true
fetch-registry: true # 是否从注册中心获取服务注册信息 默认true

编写代码调用远程接口

编写远程调用代码
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package org.akachi.eurekademo.order.controller;

import org.akachi.eurekademo.order.dto.OrderDto;
import org.akachi.eurekademo.order.model.Order;
import org.akachi.eurekademo.product.model.Product;
import org.akachi.eurekademo.order.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
* @Author akachi
* @Email zsts@hotmail.com
* @Date 2021/10/20 15:10
*/
@RestController
public class OrderController implements Serializable {
@Autowired
private RestTemplate restTemplate;

@Autowired
private DiscoveryClient discoveryClient;

@Autowired
OrderRepository orderRepository;

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}

@GetMapping("/order/list")
public HttpEntity<List<OrderDto>> getOrderList() {
List<Order> orderList = orderRepository.findAll();
List<OrderDto> orderDtoList = new ArrayList<>();
for (Order order : orderList) {
OrderDto orderDto = OrderDto.toOrderDto(order);
orderDtoList.add(orderDto);
getProducts(orderDto);
}
return new HttpEntity<>(orderDtoList);
}

private void getProducts(OrderDto order) {
StringBuffer stringBuffer = null;
List<String> serverIds = discoveryClient.getServices();
if (CollectionUtils.isEmpty(serverIds)) {
return;
}
List<ServiceInstance> serviceInstances = discoveryClient.getInstances("EUREKADEMO-SERVICE-PRODUCT");
if (CollectionUtils.isEmpty(serviceInstances)) {
return;
}
ServiceInstance serviceInstance = serviceInstances.get(0);
stringBuffer = new StringBuffer();
stringBuffer.append("http://")
.append(serviceInstance.getHost())
.append(":")
.append(serviceInstance.getPort())
.append("/product/list");
ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(
stringBuffer.toString(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Product>>() {
});
order.setProducts(responseEntity.getBody());
}
}

问题:

注入RestTemplate not found

1
2
3
4
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}

通过创建rest

LoadBalancerClient 负载均衡器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

private void getProductsByLoadBalancerClient(OrderDto order){
StringBuffer stringBuffer = null;
ServiceInstance serviceInstance = loadBalancerClient.choose("EUREKADEMO-SERVICE-PRODUCT");
if(null==serviceInstance){
return;
}
stringBuffer = new StringBuffer();
stringBuffer.append("http://")
.append(serviceInstance.getHost())
.append(":")
.append(serviceInstance.getPort())
.append("/product/list");

ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(
stringBuffer.toString(),
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Product>>() {
});
order.setProducts(responseEntity.getBody());
}
@LoadBalancer 负载均衡

通过注解负载均衡

1
2
3
4
5
6
7
8
9
private void getProductsByLoadBalancerRestTemplate(OrderDto order) {
ResponseEntity<List<Product>> responseEntity = restTemplateBalancer.exchange(
"http://EUREKADEMO-SERVICE-PRODUCT/product/list",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<Product>>() {
});
order.setProducts(responseEntity.getBody());
}

可以直接通过服务名负载均衡调用

优雅停服

  • 在product 添加actuator依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.5.5</version>
    </dependency>
  • 查看是否成功

    1
    http://localhost:18180/actuator
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "_links": {
    "self": {
    "href": "http://localhost:18180/actuator",
    "templated": false
    },
    "health": {
    "href": "http://localhost:18180/actuator/health",
    "templated": false
    },
    "health-path": {
    "href": "http://localhost:18180/actuator/health/{*path}",
    "templated": true
    }
    }
    }
  • 在配置文件中打開 shutdown端点

    1
    2
    3
    4
    5
    6
    7
    8
    management:
    endpoints:
    web:
    exposure:
    include: shutdown
    endpoint:
    shutdown:
    enabled: true

    打開shutdown请求后就可以通过访问服务请求下线服务

  • http://localhost:18180/actuator/shutdown

    image-20211021143527824

    亲求后服务会被优雅停止

    1
    2
    3
    {
    "message": "Shutting down, bye..."
    }

安全

  • 配置maven

    在所有相关节点中加入

    在 eureka server中的pom.xml中加入

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.5.5</version>
    </dependency>
  • 在eureka server中application.yml加入

    1
    2
    3
    4
    5
    spring:
    security:
    user:
    name: root
    password: 123456
  • 在所有需要連接的節點中加入 root:123456@

    1
    2
    3
    server:
    client:
    defaultZone: http://root:123456@${eureka.server.hostname}:${eureka.server.port}/eureka/

    加入账号名与密码

  • 过滤CSRF服务

    image-20211021151249582

    禁用防御机制

    添加一個WebSecurityConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package org.akachi.server.config;

    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2021/10/21 15:14
    */
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    protected void config(HttpSecurity http) throws Exception{
    super.configure(http);
    http.csrf().ignoringAntMatchers("/eureka/**");
    }
    }

    如果修改完之服務重啓能夠正常访问那感谢

Ribbon负载均衡

什么是Ribbon

ribbon不是需要独立部署的微服务。几乎所有的微服务都需要用到ribbon。

Ribbon提供了微服务的负载均衡。

image-20211021152703602

负载均衡的不同方案区别

image-20211021153100645

  1. 集中式

    image-20211021153129640

  2. 进程式

    image-20211021153147066

Ribbon负载均衡策略
  • 轮询

    RoundRobinRule

  • 响应时间权重策略

    WegihtedResponseTimeRule

    响应时间越小轮询到的可次数越少

  • 随机

    RandomRule

  • 最少并发数

    BestAvailableRule

    选择正在请求中的并发数最小的provider,除非这个provider在熔断。

  • 重试策略

    RetryRule

    首先轮询、如果不可用再替换其他服务。

  • 可用性敏感策略

    AvailabilityFilteringRule

    过滤掉不可用的provider或者过滤掉比较忙的

  • 区域敏感性策略

    ZoneAvoidanceRule

    以区域为考察的可用性敏感策略

入门案例

如果想要方便的一次性启动一堆服务可以通过这里

image-20211021232242491

  • 启动多个Product port 分别为18181,18182,18183
  • 返回端口来判断访问的是谁
  • 直接调用/order/list 查看返回是否是轮询
设置负载均衡策略
  • 添加maven cloud 2.5.5 中默认不包含

    pom.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-netflix-ribbon</artifactId>
    <version>2.2.6.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon-loadbalancer</artifactId>
    <version>2.3.0</version>
    </dependency>
  • 在OrderApplication中加入代码

    1
    2
    3
    4
    @Bean
    public RandomRule randomRule(){
    return new RandomRule();
    }
  • org.akachi.config.LoadBalanced.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package org.akachi.config;

    import com.netflix.loadbalancer.IRule;
    import org.akachi.eurekademo.order.config.TestRule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2021/10/22 0:19
    */

    @Configuration
    public class LoadBalanced {
    @Bean
    public IRule ribbonRule() {
    // return new RoundRobinRule(); //轮询
    // return new WeightedResponseTimeRule(); //加权权重
    // return new RetryRule(); //带有重试机制的轮训
    // return new RandomRule(); //随机
    return new TestRule(); //自定义规则
    }
    }
设置某个微服务的负载均衡策略
失败了下次再试
点对点直连
  • 删除pom.xml引用 spring-cloud-starter-netflix-eureka-client

  • 添加pom.xml引用spring-cloud-starter-netflix-ribbon

  • 注释application.yml中的eureka相关内容

  • 增加相关配置

    1
    2
    3
    4
    5
    6
    7
    eurekademo-service-product: #服务名称(注意大小写) restTemplate.exchange 
    ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机策略
    listOfServers: http://localhost:18182,http://localhost:18181,http://localhost:18180
    ribbon:
    eureka:
    enable: false

Consul

地址:https://www.consul.io/docs/intro