springcloud--负载均衡(ribbon)
一、项目背景
- 搭建好的springcloud项目,包含erueka模块(这里是单个,也可以多个)、服务提供者(多个)、消费者。
- 创建多个服务提供者模块,用于集群(单个业务多个提供接口,避免单个宕机或者其他因素影响服务)。
- 相同的服务提供者的服务名需要保持一直,将其在erueka注册中心进行注册。
- erueka中包含了ribbon依赖,可以不需要单独引入。
- ribbon负载均衡,引入依赖坐标,并在消费者模块的调用接口restTemplate(配置类)上添加@LoadBalanced
- 需要创建RibbonRule配置类配置一个策略对象,即将策略装配到容器中,RandomRule();//随机访问策略
- 在消费者模块的启动类上增加ribbon启动注解:@RibbonClient(name = "provider",configuration = RibbonRule.class)
二、代码步骤
-
搭建多个服务提供者
创建一个springboot项目provider-8004,并将provider-8001项目的代码复制一份到provider-8004中,因为是单机原因,这里用端口进行区分,8001是服务提供者1,8004是服务提供者2,8080是erueka注册中心,8002是消费者(这里的8003端口的项目已经删除,故略)。
8004服务提供者启动类代码:(以下8004逻辑代码与8001相同)
@SpringBootApplication @EnableEurekaClient public class Provider8004Application { public static void main(String[] args) { SpringApplication.run(Provider8004Application.class, args); } }
service层代码:
@Mapper @Repository public interface ShiroUserService { @Select("select * from usershiro") public List<ShiroUser> selectAll(); @Select("select * from usershiro where uname=#{uname}") public ShiroUser selectOne(String uname); @Select("insert into usershiro (uname,password,datasource) values (#{uname},#{password},#{datasource})") void insertOne(ShiroUser shiroUser); @Select("delete from usershiro where uname=#{uname}") void deleteOne(String uname); }
实体类代码:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ShiroUser {
private Integer uid;
private String uname;
private String password;
private String datasource;
}
controller代码
@RestController
public class ShiroUserController {
@Autowired
ShiroUserService shiroUserService;
@GetMapping("/getAll")
public List<ShiroUser> getAll(HttpServletRequest request){
System.out.println("服务端口:"+request.getServerPort()+"服务名:"+request.getServerName());
return shiroUserService.selectAll();
}
@GetMapping("/getOne")
public ShiroUser getOne(String uname){ return shiroUserService.selectOne(uname);}
}
application.xml配置文件:
server:
port: 8004
mybatis:
type-aliases-package: com.yiblue.provider8004.entity
mapper-locations: classpath:mappers/*xml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: caidongji
password: abc123
application:
name: provider
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://localhost:8080/eureka/
以上配置,已将服务注册到erueka中心,服务名,即application.name与8001提供者一样,provider
-
在消费者中的ribbon配置
在restTemplateconfig类中配置注解:@LoadBalanced
@Configuration public class restTemplateconfig { @Bean @LoadBalanced RestTemplate restTemplate(){ return new RestTemplate();} }
添加ribbon策略,创建一个配置类:
@Configuration public class RibbonRule { @Bean public IRule RibbomStrategy(){ return new AvailabilityFilteringRule(); // return new RandomRule();//随机访问策略 /* * Ribbon负载均衡策略: RoundRobinRule 轮询,默认策略。 RandomRule 随机 RetryRule 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务 WeightedResponseTimeRule 对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择 BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例 ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器 * */ } }
在消费者启动类上配置启动注解:@RibbonClient
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "provider",configuration = RibbonRule.class)
public class Consumer8002Application {
public static void main(String[] args) {
SpringApplication.run(Consumer8002Application.class, args);
}
}
- 模块启动顺序erueka>provider1>provider2>consumer。服务者的之间的顺序可以颠倒。