Spring Cloud Alibaba 使用Gateway网关
项目搭建
- 项目结构
- 搭建pped-api网关项目(在之前项目基础上添加网关)
- pom.xml
(注意版本:具体版本可到官网查看:https://spring.io/projects/spring-cloud#learn ,点击版本后面的Reference Doc.查看)<!--springBoot--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.12.RELEASE</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> </dependency> <!--nacos--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.3.RELEASE</version> </dependency>
- application.yml:(注意格式,两个路由是之前的两个子项目)
server: port: 8888 spring: application: name: pped-api cloud: nacos: discovery: server-addr: 127.0.0.1:8848 group: PPED_GROUP gateway: routes: #数组形式 - id: nacos #路由唯一标识 uri: lb://pped-nacos #想要转发到的地址,从nacos注册中心上拉取,lb:负载均衡轮询 predicates: #断言 配置哪个路径才转发 - Path=/nacos/** filters: - StripPrefix=1 #去掉第一层前缀 - id: sentinel uri: lb://pped-sentinel predicates: - Path=/sentinel/** filters: - StripPrefix=1 discovery: locator: enabled: true
- 启动类加上注释
@EnableDiscoveryClient public class PpedApiApplication { public static void main(String[] args) { SpringApplication.run(PpedApiApplication.class, args); } }
测试
- 访问localhost:8888/nacos/test
- 完成
负载均衡
- nacos默认存在负载均衡
- 在之前基础上启动两个实例进行测试
- 修改TestController
访问时返回端口 @Value("${local.server.port}") private int port; return stringBuilder.toString() + " port:" + port;
- 配置端口:idea右上角点击Edit Configurations
- 点击左上角复制图标,复制配置(copy configuration)配置端口
- 设置Programs arguments: –server.port=17072
- 保存
- 以新配置文件再启动一个服务
- 进入nacos控制台可以发现两个实例
- 不断访问localhost:8888/nacos/test
- 可以发现在交替访问两个实例
自定义权重
- 通过nacos控制台设置权重时,实际上并未生效,因为负载均衡器里使用的默认规则是 RoundRobinRule(轮询)
- 想要自定义权重需要启用Robin的NacosRule,替换默认的Rule
- 改动启动类
public class PpedApiApplication { public static void main(String[] args) { SpringApplication.run(PpedApiApplication.class, args); } @Bean public IRule loadBalanceRule(){ return new NacosRule(); } }
- 改动之后发现使用网关进行转发时报错,服务找不到
- 原因是gateway默认使用DEFAULT_GROUP,这里改动了group所以服务找不到
- 需要写一个自定义Rule
@Slf4j public class NacosWeightedRule extends AbstractLoadBalancerRule { @Autowired private NacosDiscoveryProperties nacosDiscoveryProperties; /** * 读取配置文件,并初始化NacosWeightedRule * * @param iClientConfig iClientConfig */ @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { // do nothing } @Override public Server choose(Object key) { BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer(); // 需要请求的微服务名称 String name = loadBalancer.getName(); // 获取服务发现的相关API NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); String group = nacosDiscoveryProperties.getGroup(); try { // 调用该方法时nacos client会自动通过基于权重的负载均衡算法选取一个实例 Instance instance = namingService.selectOneHealthyInstance(name, group, true); log.info("=============invoke serviceName:{}, ip:{}, port:{}", instance.getServiceName(), instance.getIp(), instance.getPort()); return new NacosServer(instance); } catch (NacosException e) { return null; } } }
- 修改启动类
public class PpedApiApplication { public static void main(String[] args) { SpringApplication.run(PpedApiApplication.class, args); } @Bean public IRule loadBalanceRule(){ return new NacosWeightedRule(); } }
- 在控制台给两个服务设置权重,可以发现两服务按权重交替被访问