✨ 负载均衡使用
This commit is contained in:
parent
3e61995bc6
commit
f12f1a6ed3
|
@ -28,12 +28,12 @@ sudo systemctl daemon-reload && sudo systemctl restart docker
|
||||||
|
|
||||||
#### MySQL配置问题
|
#### MySQL配置问题
|
||||||
|
|
||||||
| **特性** | `**my.cnf**` | `**conf.d**` **目录** |
|
| **特性** | `**my.cnf**` | `**conf.d**` **目录** |
|
||||||
| ------------ | ---------------------------- | -------------------------- |
|
|----------|:--------------------|:-------------------:|
|
||||||
| **文件类型** | 单个文件 | 目录,包含多个 `.cnf` 文件 |
|
| **文件类型** | 单个文件 | 目录,包含多个 `.cnf` 文件 |
|
||||||
| **配置方式** | 集中式配置 | 分布式配置 |
|
| **配置方式** | 集中式配置 | 分布式配置 |
|
||||||
| **优先级** | 高(覆盖 `conf.d` 中的配置) | 低(被 `my.cnf` 覆盖) |
|
| **优先级** | 高(覆盖 `conf.d` 中的配置) | 低(被 `my.cnf` 覆盖) |
|
||||||
| **适用场景** | 全局配置,核心配置 | 模块化配置,便于扩展和维护 |
|
| **适用场景** | 全局配置,核心配置 | 模块化配置,便于扩展和维护 |
|
||||||
|
|
||||||
#### MongoDB配置
|
#### MongoDB配置
|
||||||
|
|
||||||
|
@ -95,16 +95,16 @@ db.createUser({ user: 'admin', pwd: '02120212', roles: [ { role: "root", db: "ad
|
||||||
|
|
||||||
如果休要所有的微服务环境,可以直接复制下面的内容,看清楚目录是否和自己需要的一样。
|
如果休要所有的微服务环境,可以直接复制下面的内容,看清楚目录是否和自己需要的一样。
|
||||||
|
|
||||||
| 功能 | 旧版 (docker-compose) | 新版 (docker compose) |
|
| 功能 | 旧版 (docker-compose) | 新版 (docker compose) |
|
||||||
| -------------------- | ----------------------- | ----------------------- |
|
|--------------|-------------------------|-------------------------|
|
||||||
| **启动服务** | docker-compose up -d | docker compose up -d |
|
| **启动服务** | docker-compose up -d | docker compose up -d |
|
||||||
| **停止服务** | docker-compose down | docker compose down |
|
| **停止服务** | docker-compose down | docker compose down |
|
||||||
| **查看日志** | docker-compose logs -f | docker compose logs -f |
|
| **查看日志** | docker-compose logs -f | docker compose logs -f |
|
||||||
| **列出容器** | docker-compose ps | docker compose ps |
|
| **列出容器** | docker-compose ps | docker compose ps |
|
||||||
| **停止不删除容器** | docker-compose stop | docker compose stop |
|
| **停止不删除容器** | docker-compose stop | docker compose stop |
|
||||||
| **启动已停止的容器** | docker-compose start | docker compose start |
|
| **启动已停止的容器** | docker-compose start | docker compose start |
|
||||||
| **重启服务** | docker-compose restart | docker compose restart |
|
| **重启服务** | docker-compose restart | docker compose restart |
|
||||||
| **构建镜像** | docker-compose build | docker compose build |
|
| **构建镜像** | docker-compose build | docker compose build |
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: cloud-services
|
name: cloud-services
|
||||||
|
@ -131,8 +131,8 @@ services:
|
||||||
restart: always
|
restart: always
|
||||||
privileged: true
|
privileged: true
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: redis_master
|
container_name: redis_master
|
||||||
image: redis:7.0.10
|
image: redis:7.0.10
|
||||||
|
@ -149,8 +149,8 @@ services:
|
||||||
- "--tcp-keepalive 300"
|
- "--tcp-keepalive 300"
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
container_name: minio_master
|
container_name: minio_master
|
||||||
|
@ -165,7 +165,7 @@ services:
|
||||||
command: "server /data --console-address :9090"
|
command: "server /data --console-address :9090"
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
mongodb:
|
mongodb:
|
||||||
image: mongo:latest
|
image: mongo:latest
|
||||||
|
@ -180,8 +180,8 @@ services:
|
||||||
- ~/docker/docker_data/mongo/logs:/data/log
|
- ~/docker/docker_data/mongo/logs:/data/log
|
||||||
command: "mongod --config /data/configdb/mongod.conf"
|
command: "mongod --config /data/configdb/mongod.conf"
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
image: rabbitmq:management
|
image: rabbitmq:management
|
||||||
container_name: rabbitmq
|
container_name: rabbitmq
|
||||||
|
@ -199,7 +199,7 @@ services:
|
||||||
- RABBITMQ_DEFAULT_VHOST=/
|
- RABBITMQ_DEFAULT_VHOST=/
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
nacos:
|
nacos:
|
||||||
image: nacos/nacos-server:v2.4.3
|
image: nacos/nacos-server:v2.4.3
|
||||||
container_name: nacos
|
container_name: nacos
|
||||||
|
@ -210,8 +210,8 @@ services:
|
||||||
- MODE=standalone
|
- MODE=standalone
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
sentinel:
|
sentinel:
|
||||||
image: bladex/sentinel-dashboard:1.8.8
|
image: bladex/sentinel-dashboard:1.8.8
|
||||||
container_name: sentinel
|
container_name: sentinel
|
||||||
|
@ -220,7 +220,7 @@ services:
|
||||||
privileged: true
|
privileged: true
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
seata-server:
|
seata-server:
|
||||||
image: apache/seata-server:2.3.0.jdk21
|
image: apache/seata-server:2.3.0.jdk21
|
||||||
|
@ -229,7 +229,7 @@ services:
|
||||||
- "8091:8091"
|
- "8091:8091"
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloud
|
- cloud
|
||||||
|
|
||||||
networks: # 定义网络
|
networks: # 定义网络
|
||||||
cloud: # 定义名为 auth 的网络
|
cloud: # 定义名为 auth 的网络
|
||||||
|
@ -244,24 +244,81 @@ networks: # 定义网络
|
||||||
发现服务信息。
|
发现服务信息。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
for (String service : discoveryClient.getServices()) {
|
@SpringBootTest()
|
||||||
System.out.println(service);
|
public class DiscoveryTest {
|
||||||
|
|
||||||
for (ServiceInstance instance : discoveryClient.getInstances(service)) {
|
@Autowired
|
||||||
System.out.println("IP地址:" + instance.getHost());
|
private DiscoveryClient discoveryClient;
|
||||||
System.out.println("端口号" + instance.getPort());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("----------------------------------------------");
|
@Autowired
|
||||||
|
private NacosDiscoveryClient nacosDiscoveryClient;
|
||||||
|
|
||||||
// 两个方式一样,DiscoveryClient 是 Spring自带的 NacosDiscoveryClient是 Nacos
|
@Test
|
||||||
for (String service : nacosDiscoveryClient.getServices()) {
|
void discoveryClientTest() {
|
||||||
System.out.println(service);
|
for (String service : discoveryClient.getServices()) {
|
||||||
|
System.out.println(service);
|
||||||
|
|
||||||
for (ServiceInstance instance : nacosDiscoveryClient.getInstances(service)) {
|
for (ServiceInstance instance : discoveryClient.getInstances(service)) {
|
||||||
System.out.println("IP地址:" + instance.getHost());
|
System.out.println("IP地址:" + instance.getHost());
|
||||||
System.out.println("端口号" + instance.getPort());
|
System.out.println("端口号" + instance.getPort());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("----------------------------------------------");
|
||||||
|
|
||||||
|
// 两个方式一样,DiscoveryClient 是 Spring自带的 NacosDiscoveryClient是 Nacos
|
||||||
|
for (String service : nacosDiscoveryClient.getServices()) {
|
||||||
|
System.out.println(service);
|
||||||
|
|
||||||
|
for (ServiceInstance instance : nacosDiscoveryClient.getInstances(service)) {
|
||||||
|
System.out.println("IP地址:" + instance.getHost());
|
||||||
|
System.out.println("端口号" + instance.getPort());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 远程调用
|
||||||
|
|
||||||
|
订单模块调用远程商品模块,使用了nacos,可以使用`RestTemplate`,其中`RestTemplate`是线程安全的,只要注册一次全局都是可以使用。
|
||||||
|
|
||||||
|
**RestTemplate源码**
|
||||||
|
|
||||||
|
继承了`InterceptingHttpAccessor`,在`InterceptingHttpAccessor`中,使用了单例模式。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public ClientHttpRequestFactory getRequestFactory() {
|
||||||
|
List<ClientHttpRequestInterceptor> interceptors = this.getInterceptors();
|
||||||
|
if (!CollectionUtils.isEmpty(interceptors)) {
|
||||||
|
ClientHttpRequestFactory factory = this.interceptingRequestFactory;
|
||||||
|
if (factory == null) {
|
||||||
|
factory = new InterceptingClientHttpRequestFactory(super.getRequestFactory(), interceptors);
|
||||||
|
this.interceptingRequestFactory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory;
|
||||||
|
} else {
|
||||||
|
return super.getRequestFactory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**实现远程调用**
|
||||||
|
|
||||||
|
如果我们的服务启动了多个,在下面代码中即使一个服务宕机也可以做到远程调用。
|
||||||
|
|
||||||
|
```java
|
||||||
|
private Product getProductFromRemote(Long productId) {
|
||||||
|
// 获取商品服务所有及其的 IP+port
|
||||||
|
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
|
||||||
|
ServiceInstance instance = instances.get(0);
|
||||||
|
|
||||||
|
// 远程URL
|
||||||
|
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/api/product/" + productId;
|
||||||
|
|
||||||
|
// 2. 远程发送请求
|
||||||
|
log.info("远程调用:{}", url);
|
||||||
|
return restTemplate.getForObject(url, Product.class);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -68,6 +68,10 @@
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- knife4j -->
|
<!-- knife4j -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
|
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ public class OrderServiceImpl implements OrderService {
|
||||||
|
|
||||||
private final DiscoveryClient discoveryClient;
|
private final DiscoveryClient discoveryClient;
|
||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
|
private final LoadBalancerClient loadBalancerClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建订单信息
|
* 创建订单信息
|
||||||
|
@ -30,7 +32,7 @@ public class OrderServiceImpl implements OrderService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Order createOrder(Long productId, Long userId) {
|
public Order createOrder(Long productId, Long userId) {
|
||||||
Product product = getProductFromRemote(productId);
|
Product product = getProductFromRemoteWithLoadBalancer(productId);
|
||||||
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
order.setId(1L);
|
order.setId(1L);
|
||||||
|
@ -40,13 +42,19 @@ public class OrderServiceImpl implements OrderService {
|
||||||
order.setNickName("在资质");
|
order.setNickName("在资质");
|
||||||
order.setAddress("地址地址。。。");
|
order.setAddress("地址地址。。。");
|
||||||
|
|
||||||
// TODO 远程查询
|
// 远程查询
|
||||||
order.setProductList(List.of(product));
|
order.setProductList(List.of(product));
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程调用商品模块 --- 自己实现
|
||||||
|
*
|
||||||
|
* @param productId 商品id
|
||||||
|
* @return 商品对象
|
||||||
|
*/
|
||||||
private Product getProductFromRemote(Long productId) {
|
private Product getProductFromRemote(Long productId) {
|
||||||
// 获取商品服务所有及其的 IP+port
|
// 1. 获取商品服务所有及其的 IP+port
|
||||||
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
|
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
|
||||||
ServiceInstance instance = instances.get(0);
|
ServiceInstance instance = instances.get(0);
|
||||||
|
|
||||||
|
@ -57,4 +65,22 @@ public class OrderServiceImpl implements OrderService {
|
||||||
log.info("远程调用:{}", url);
|
log.info("远程调用:{}", url);
|
||||||
return restTemplate.getForObject(url, Product.class);
|
return restTemplate.getForObject(url, Product.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程调用商品模块 --- 负载均衡
|
||||||
|
*
|
||||||
|
* @param productId 商品id
|
||||||
|
* @return 商品对象
|
||||||
|
*/
|
||||||
|
private Product getProductFromRemoteWithLoadBalancer(Long productId) {
|
||||||
|
// 1. 获取商品服务所有及其的 IP+port
|
||||||
|
ServiceInstance instance = loadBalancerClient.choose("service-product");
|
||||||
|
|
||||||
|
// 远程URL
|
||||||
|
String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/api/product/" + productId;
|
||||||
|
|
||||||
|
// 2. 远程发送请求
|
||||||
|
log.info("负载均衡远程调用:{}", url);
|
||||||
|
return restTemplate.getForObject(url, Product.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||||
<title>SpringCloud微服务复习教程</title>
|
<title>SpringCloud微服务复习教程-Order模块</title>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap"
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap"
|
||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>SpringCloud微服务复习教程</h1>
|
<h1>SpringCloud微服务复习教程-Order模块</h1>
|
||||||
<p>掌握微服务架构的核心概念与实践,从服务注册发现到分布式配置,全面复习SpringCloud生态系统的关键组件</p>
|
<p>掌握微服务架构的核心概念与实践,从服务注册发现到分布式配置,全面复习SpringCloud生态系统的关键组件</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||||
<title>SpringCloud微服务复习教程</title>
|
<title>SpringCloud微服务复习教程-Product模块</title>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap"
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap"
|
||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>SpringCloud微服务复习教程</h1>
|
<h1>SpringCloud微服务复习教程-Product模块</h1>
|
||||||
<p>掌握微服务架构的核心概念与实践,从服务注册发现到分布式配置,全面复习SpringCloud生态系统的关键组件</p>
|
<p>掌握微服务架构的核心概念与实践,从服务注册发现到分布式配置,全面复习SpringCloud生态系统的关键组件</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -103,6 +103,7 @@ rabbitmq:
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> **@PostConstruct 注解**
|
> **@PostConstruct 注解**
|
||||||
|
>
|
||||||
> **作用**:在Bean依赖注入完成后执行初始化方法(构造器之后,`afterPropertiesSet()`之前)。
|
> **作用**:在Bean依赖注入完成后执行初始化方法(构造器之后,`afterPropertiesSet()`之前)。
|
||||||
>
|
>
|
||||||
> **特点**:
|
> **特点**:
|
||||||
|
@ -116,6 +117,7 @@ rabbitmq:
|
||||||
> - 避免耗时操作,推荐轻量级初始化
|
> - 避免耗时操作,推荐轻量级初始化
|
||||||
>
|
>
|
||||||
> **替代方案**:
|
> **替代方案**:
|
||||||
|
>
|
||||||
> `InitializingBean`接口 或 `@Bean(initMethod="xxx")`
|
> `InitializingBean`接口 或 `@Bean(initMethod="xxx")`
|
||||||
|
|
||||||
RabbitMQ配置
|
RabbitMQ配置
|
||||||
|
|
Loading…
Reference in New Issue