文章目录
Ribbon简介
Ribbon是一个客户端的负载均衡(Load Balancer,简称LB)器,它提供对大量的HTTP和TCP客户端的访问控制。
负载均衡简介
集中式
即在服务的消费方和提供方之间使用独立的LB设施,可以是硬件,如F5,也可以是软件,如nginx,由该设施负责把访问请求通过某种策略转发至服务的提供方;
进程内
将LB逻辑集成到消费方,消费方从服务注册中心获取可用服务列表,然后根据指定负载均衡策略选择合适的服务器。Ribbon就属于该方式。
Ribbon负载策略
- RoundRobinRule 轮询
轮询服务列表List的index,选择index对应位置的服务。 - RandomRule 随机
随机服务列表List的index,选择index对应位置的服务。 - RetryRule 重试
指定时间内,重试(请求)某个服务不成功达到指定次数,则不再请求该服务。
Feign简介
Feign 是一个声明式的 Web Service 客户端。它的出现使开发 Web Service 客户端变得很简单。使用 Feign 只需要创建一个接口加上对应的注解,比如:@FeignClient 接口类注解。
执行流程
- 主程序入口添加 @EnableFeignClients 注解,开启对 FeignClient 接口扫 描加载。接口使用@FeignClient注解标识。
- 调用Feign 接口中的方法被时,通过JDK的代理的方式,生成具体的 RequestTemplate。
- RequestTemplate 生成 Request请求,结合Ribbon实现服务调用负载均衡策略。
项目结构图
模块描述
Eureka注册中心
why-eureka-2001
两个服务提供方
why-provider-3001
why-provider-3002
Ribbon服务调用
why-consume-1001
Feign服务调用
why-consume-1002
Eureka注册中心
所属模块why-eureka-2001
核心依赖
<!--eureka-server服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
yml配置
server:
port: 2001
spring:
application:
name: why-eureka-2001
eureka:
instance:
instance-id: localhost
hostname: localhost
prefer-ip-address: true
client:
# false表示不向注册中心注册自己
register-with-eureka: false
# false表示该端就是注册中心,维护服务实例,不去检索服务
fetch-registry: false
service-url:
# 单点注册中心
defaultZone: http://localhost:2001/eureka/
eureka 注解配置
@SpringBootApplication
@EnableEurekaServer // 注册中心注解
public class Application_2001 {
public static void main(String[] args) {
SpringApplication.run(Application_2001.class,args) ;
}
}
Ribbon服务调用
接收方
所属模块:why-consume-1001
核心依赖
<!-- Eureka 组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- Ribbon 组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
YML配置
server:
port: 1001
spring:
application:
name: why-consume-1001
eureka:
instance:
hostname: consume-1001
prefer-ip-address: true
client:
service-url:
# 集群注册中心
defaultZone: http://localhost:2001/eureka/
registerWithEureka: true
fetchRegistry: true
ribbion:
eureka:
enable: true
启动注解配置
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient
public class Application_1001 {
public static void main(String[] args) {
SpringApplication.run(Application_1001.class,args) ;
}
}
配置文件
@Configuration
public class LoadConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate (RestTemplateBuilder builder){
return builder.build();
}
@Bean
public IRule getIRule (){
// 默认轮询算法
// return new RoundRobinRule() ;
// 重试算法:默认情况,访问某个服务连续三次失败,就不会再访问
// return new RetryRule() ;
// 随机算法
return new RandomRule() ;
}
}
调用方式
@RestController
public class ConsumeController {
@Autowired
private RestTemplate restTemplate ;
@RequestMapping("/showInfo")
public String showInfo (){
return restTemplate.getForObject("http://WHY-PROVIDER-3001/getAuthorInfo/1",String.class) ;
}
}
这里的WHY-PROVIDER-3001就是why-provider-3001
服务提供方的配置文件。在eureka中显示是大写的,两个服务提供方的这块配置相同,Ribbon正基于此,实现多个服务调用的负载均衡。
spring:
application:
name: why-provider-3001
提供方
所属模块:why-provider-3001
核心依赖
<!-- 将微服务provider侧注册进eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
YML配置
server:
port: 3001
spring:
application:
name: why-provider-3001
eureka:
instance:
hostname: provider-3001
prefer-ip-address: true
client:
service-url:
defaultZone: http://localhost:2001/eureka/
registerWithEureka: true
fetchRegistry: true
注解配置
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient
public class Application_3001 {
public static void main(String[] args) {
SpringApplication.run(Application_3001.class,args) ;
}
}
提供方式
@RestController
public class ProviderController {
private static final Logger LOG = LoggerFactory.getLogger(ProviderController.class) ;
@RequestMapping("/getInfo")
public String getInfo (){
LOG.info("provider-3001");
return "success" ;
}
@RequestMapping(value = "/getAuthorInfo/{authorId}",method = RequestMethod.GET)
public String getAuthorInfo (@PathVariable("authorId") String authorId) {
return "我最帅了"+authorId ;
}
}
Feign服务调用
接收方
所属模块:why-consume-1002
核心依赖
<!-- Feign组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- Eureka 组件 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
YML配置
server:
port: 1002
spring:
application:
name: why-consume-1002
eureka:
instance:
hostname: consume-1002
prefer-ip-address: true
client:
service-url:
# 集群注册中心
defaultZone: http://localhost:2001/eureka/
registerWithEureka: true
fetchRegistry: true
ribbion:
eureka:
enable: true
启动类注解
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient
// 因为包名路径不同,需要加basePackages属性
@EnableFeignClients(basePackages={"cloud.block.code.service"})
public class Application_1002 {
public static void main(String[] args) {
SpringApplication.run(Application_1002.class,args) ;
}
}
配置文件
@FeignClient(value = "why-provider-3002")
public interface GetAuthorService {
@RequestMapping(value = "/getAuthorInfo/{authorId}",method = RequestMethod.GET)
String getAuthorInfo (@PathVariable("authorId") String authorId) ;
}
调用方式
@RestController
public class ConsumeController {
@Resource
private GetAuthorService getAuthorService ;
@RequestMapping(value = "/getAuthorInfo")
public String getAuthorInfo () {
return getAuthorService.getAuthorInfo("1") ;
}
}
提供方
所属模块:why-provider-3002
核心依赖
<!-- 将微服务provider侧注册进eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
YML配置
server:
port: 3002
spring:
application:
name: why-provider-3002
eureka:
instance:
hostname: provider-3002
prefer-ip-address: true
client:
service-url:
defaultZone: http://localhost:2001/eureka/
registerWithEureka: true
fetchRegistry: true
启动类注解
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient
public class Application_6002 {
public static void main(String[] args) {
SpringApplication.run(Application_6002.class,args) ;
}
}
提供方式
@RestController
public class ProviderController {
private static final Logger LOG = LoggerFactory.getLogger(ProviderController.class) ;
@RequestMapping("/getInfo")
public String getInfo (){
return "success" ;
}
@RequestMapping(value = "/getAuthorInfo/{authorId}",method = RequestMethod.GET)
public String getAuthorInfo (@PathVariable("authorId") String authorId) {
return "我最帅了"+authorId ;
}
}