- 一、客户端负载均衡——Netflix Ribbon/Feign
- 1.1、负载均衡介绍
- 1.2、使用之前,先进行集群
- 1.2.1、注册中心集群
- 1.2.2、服务提供者集群
- 1.3、负载均衡实现-Ribbon
- 1.3.1、集成原理
- 1.3.2、导包
- 1.3.3、在服务消费者创建类
- 1.3.4、随机负载均衡
- 1.4、负载均衡实现-Feign
- 1.4.1、feign的特性
- 1.4.2、导包
- 1.4.3、配置application.yml(略)、公共代码
- 1.4.4、服务消费者调用
一、客户端负载均衡——Netflix Ribbon/Feign
1.1、负载均衡介绍
:英文名称为Load Balance, 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
1.2、使用之前,先进行集群
如果只有一个注册中心服务器,会存在单点故障所以要集群
1.2.1、注册中心集群
- 拷贝一份注册中心项目
- 搭建集群,修改各自application.yml配置
- springcloud-demo-eureka
server:
#端口
port: 7001
eureka:
instance:
#服务注册中心实例的主机名
hostname: localhost
prefer-ip-address: true #显示ip地址
server:
#关闭自我保护机制,防止失效的服务也被一直访问 (开发环境)
enable-self-preservation: false
#该配置可以修改检查失效服务的时间,每隔5s检查失效服务,默认该配置是 60s (开发环境)
eviction-interval-timer-in-ms: 3000
client:
#是否向服务注册中心注册自己
registerWithEureka: false
#是否检索服务
fetchRegistry: false
#服务注册中心的配置内容,指定服务注册中心的位置
serviceUrl:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
defaultZone: http://localhost:7002/eureka/ #多机注册中心的地址,用逗号隔开
- springcloud-demo-eureka-2
server:
#端口
port: 7002
eureka:
instance:
#服务注册中心实例的主机名
hostname: localhost
prefer-ip-address: true #显示ip地址
server:
#关闭自我保护机制,防止失效的服务也被一直访问 (开发环境)
enable-self-preservation: false
#该配置可以修改检查失效服务的时间,每隔5s检查失效服务,默认该配置是 60s (开发环境)
eviction-interval-timer-in-ms: 3000
client:
#是否向服务注册中心注册自己
registerWithEureka: false
#是否检索服务
fetchRegistry: false
#服务注册中心的配置内容,指定服务注册中心的位置
serviceUrl:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置
defaultZone: http://localhost:7001/eureka/ #多机配置,用逗号隔开
- 启动测试
那么,在你注册服务的时候,只需要注册到两个注册中心就行了
1.2.2、服务提供者集群
只需拷贝该服务提供者项目,修改配置即可
1.3、负载均衡实现-Ribbon
1.3.1、集成原理
1.3.2、导包
在服务提供者中pom.xml
<!--springboot支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--客户端负载均衡实现 ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
1.3.3、在服务消费者创建类
- 代码,配置restTemplate
@Configuration //相当于xml的beans标签,spring扫描到就可以注入
public class CfgBean {
@Bean//相当于xml中的bean标签,id为方法名
@LoadBalanced //开启负载均衡,默认是轮询
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
---------------------------controller层-----------------------------------------
@RestController
public class UserController {
//注入restTemplate
@Autowired
RestTemplate restTemplate;
@Autowired
EmpCllent empCllent;
//restful风格
@RequestMapping("/getEmp/{id}")
public Object getEmp(@PathVariable("id") Integer id){
//通过服务名从注册中心获取服务列表,通过负载均衡调用
String url = "http://springcloud-demo-ehr/getEmp/"+id;
User user = restTemplate.getForObject(url, User.class);
return user;
}
}
1.3.4、随机负载均衡
@Configuration //相当于xml的beans标签
public class CfgBean {
@Bean//相当于xml中的bean标签,id为方法名
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
//采用随机负载均衡
@Bean
public IRule myRule(){
return new RandomRule();
}
}
1.4、负载均衡实现-Feign
- 前面当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,显得太过麻烦
Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。
1.4.1、feign的特性
- 可插拔的注解支持,包括Feign注解和JAX-RS注解;
- 支持可插拔的HTTP编码器和解码器;
- 支持Hystrix和它的Fallback;
- 支持Ribbon的负载均衡;
- 支持HTTP请求和响应的压缩。
这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。
Feign是以接口方式进行调用,而不是通过RestTemplate来调用,feign底层还是ribbo,它进行了封装,让我们调用起来更加简单.
1.4.2、导包
在服务提供者的pom文件中
<dependencies>
<!--公共代码依赖-->
<dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--feign的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
1.4.3、配置application.yml(略)、公共代码
@FeignClient(value="springcloud-demo-ehr")//服务的名字,通过服务的名字找到该服务的controller
public interface EmpCllent {
@RequestMapping("/getEmp/{id}")
Object getEmp(@PathVariable("id") Integer id);
}
注意:要和服务提供者里面访问地址和参数等保持一致。
1.4.4、服务消费者调用
- 导入服务提供者接口依赖
<!--依赖接口-->
<dependency>
<groupId>springcloud-demo</groupId>
<artifactId>ehr-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--feign的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 启动类 扫描接口包
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages="cn.ykf.feignClient")//如果不在当前包,需要配置basePackages
public class Crm_RunApp {
public static void main(String[] args) {
SpringApplication.run(Crm_RunApp.class, args);
}
}
- controller层调用接口
@RestController
public class UserController {
//注入restTemplate
@Autowired
RestTemplate restTemplate;
@Autowired
EmpCllent empCllent;
//restful风格
@RequestMapping("/getEmp2/{id}")
public Object getEmp2(@PathVariable("id") Integer id){
return empCllent.getEmp(id); //会调用服务提供者的controller对应的方法
}
}
- 测试:
启动注册中心
启动服务提供者
启动服务消费者测试