文章目录
1.创建一个maven项目(父工程)
删除的多余的src文件夹
引入公共依声明(版本管理):
<?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>
<packaging>pom</packaging>
<modules>
<module>userservice</module>
<module>gateway</module>
<module>common</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.redocloud</groupId>
<artifactId>crazy</artifactId>
<version>1.0</version>
<name>crazy Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring Settings -->
<spring-boot-admin.version>2.1.5</spring-boot-admin.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
<spring-cloud-alibaba.version>0.9.0.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- spring cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.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>
2.创建公共模块(一般是工具类或者公共的配置或者接口、注解、枚举等)
当然我这里只是加了一个工具类,这里暂时没有什么依赖,按需导入对应的一些工具包,如fastjson、gson等
3.创建Gateway模块
如创建一个gateway网关:
选中父模块=>New=>Module
配置模块信息(我这里报错是因为我已经创建了gateway这个工程了,这里只是作为演示)
导入依赖:
<?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>crazy</artifactId>
<groupId>cn.redocloud</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<name>gateway</name>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--这就是上面我们定义的公共模块的包,导入后才能使用,否者是识别不到的-->
<dependency>
<groupId>cn.redocloud</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
如下:
gateway的配置:
server:
port: 9000
spring:
profiles:
active: dev
application:
name: gateway
cloud:
gateway:
routes:
- id: userservice
uri: lb://userservice
predicates:
- Path=/user/**
以上url为满足predicates中定义的条件后访问的服务
lb://服务名 lb的含义是均衡负载 调用服务
Path = /user/**是指请求的url满足条件为/user开头时会访问uri中定义的服务或者url或者websocket地址
3.创建userservice
目的:查看gateway是否真的做到了均衡负载
依赖如下:
<?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>crazy</artifactId>
<groupId>cn.redocloud</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.redocloud</groupId>
<artifactId>userservice</artifactId>
<version>1.0</version>
<name>userservice Maven Webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
bootstrap.yml
spring:
cloud:
nacos:
config:
namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
group: dev
server-addr: 127.0.0.1:8848
file-extension: yaml
discovery:
namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
server-addr: 127.0.0.1:8848
创建启动类+控制器
因为要测试是否做到负载均衡,所以这里需要启动两个userservice
第一个userservice的配置如下:端口为9001
server:
port: 9001
spring:
profiles:
active: dev
application:
name: userservice
选中Edit Configurations
点击勾选允许并行运行Allow parallel run
启动:(不要用Jrebel启动)
启动成功,端口为9001
配置第二个userservice:
将刚刚的配置文件改为,仅修改端口为9002
server:
port: 9002
spring:
profiles:
active: dev
application:
name: userservice
修改Controller内容返回User2:
同样,Edit Configurations
新增一个启动器 UserServiceApplication2,启动类仍然为UserServiceApplication类
点击勾选允许并行运行Allow parallel run
启动(不要使用Jrebel启动)
访问同一个接口:
出现两种不同的返回,说明负载均衡成功了,当然这是网关的均衡负载。
4.创建OrderService
目的:整合openFeign ,测试OpenFeign的均衡负载
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>crazy</artifactId>
<groupId>cn.redocloud</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>orderservice</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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-openfeign</artifactId>
</dependency>
</dependencies>
</project>
application.yml配置
server:
port: 9003
spring:
profiles:
active: dev
application:
name: orderservice
feign:
hystrix:
enabled: true #默认关闭 不开的话,如果FeignClient的fallback不生效
bootstrap.yml 同上没有变化
spring:
cloud:
nacos:
config:
namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
group: dev
server-addr: 127.0.0.1:8848
file-extension: yaml
discovery:
namespace: 9eeffe66-d561-4b00-a42c-38d13fd5cd09
server-addr: 127.0.0.1:8848
编写FeignClient,调用上面的userservice服务
@FeignClient(name = "userservice",fallback = UserClientFallback.class)
public interface UserClient {
@RequestMapping("/user")
String getUser();
}
设置熔断类:
@Component
public class UserClientFallback implements UserClient {
@Override
public String getUser() {
return "null";
}
}
在Controller中注入:
@RequestMapping("/order")
@RestController
@Slf4j
public class OrderController {
@Autowired
UserClient userClient;
@RequestMapping
public String getUser(){
log.info("类为{}",userClient);
return userClient.getUser();
}
}
启动orderservice,访问order接口:
可以看到访问同一个接口时,两个结果的不同,这就是openfeign自带的均衡负载(当然,这个从业务上将不应该如此,而是应该user服务调用orderservice,这里只是做简单示例,具体需要考虑业务)
测试熔断:关闭两个userservice服务,再访问/order接口:
返回的是我们在熔断类中定义的信息(这里必须配置
feign:
hystrix:
enabled: true #默认关闭 否则返回的为500错误)
5.Gateway中Redis限流
引入依赖
<!--#### Redis限流 start ####-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!-- commons-pool2对象池依赖 这个是需要引入的,spring-boot-starter-data-redis-reactive部分地方依赖了这块内容-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--#### Redis限流 end ####-->
在yml中新增filters,名称必须为RequestRateLimiter,以下配置参数限流和ip限流
配置限流方式:(以下仅为其中一种限流,也可以在过滤器中重写方法的形式来自己使用Redis等实现此功能)
/**
* @Author: ChenTaoTao
* @Date: 2021/12/20 22:24
* @Describe:
*/
@Configuration
public class LimiterConfig {
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
//定义一个ipKeyResolver
@Bean
public KeyResolver ipKeyResolver(){
//新写法 lamda表达式 相当于new KeyResolver(){ 重写方法 }
return exchange -> {
//获取访问者的ip地址, 通过访问者ip地址进行限流, 限流使用的是Redis中的令牌桶算法
String hostString = exchange.getRequest().getRemoteAddress().getHostString();
return Mono.just(hostString);
};
}
}