一、负载均衡是什么?
在以前,项目访问量非常大的时候,往往一台服务器无法承载这么大的压力。一般采用的是服务器集群来缓解服务器压力。但是多个服务器又这么连接那?这时候就可以通过负载均衡来实现。负载均衡:就是通过一个代理服务器,代理服务器在通过算法来访问服务器集群中的一台服务器。最初我们实现负载均衡的方式是使用Nginx,但是SpringCloud组件中提供了SpringCloud Netflix Ribbon来实现负载均衡
二、Riboon简介
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。如图。
三、Riboon学习
3.1Eureka的搭建
- maven
<parent>
<groupId>com.yk</groupId>
<artifactId>cloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springcloud-eureka-ribbon</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
- yml配置
spring:
application:
name: spring-cloud-eureka-server
server:
port: 801
eureka:
client:
##让自己不需要注册在上面禁止客户端注册,表明自己是一个eureka server
register-with-eureka: false
fetch-registry: false
service-url:
#服务注册
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
instance:
hostname: localhost
- 启动入口
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaServer
public class RibboneurekaApplication {
public static void main(String[] args) {
SpringApplication.run(RibboneurekaApplication.class, args);
}
}
3.2服务提供者搭建
- maven
<parent>
<groupId>com.yk</groupId>
<artifactId>cloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springcloud-service-provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
- 配置
#服务名称和端口
spring.application.name=spring-cloud-service-provider
server.port=9090
#连接Eureka Server
eureka.client.serviceUrl.defaultZone = http://localhost:801/eureka/
#显示IP和端口
eureka.instance.hostname = localhost
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id: ${spring.cloud.client.ip-address}:${server.port}
- 启动入口
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
- 测试Controller
@RestController
public class ServiceProviderController {
@Value("${server.port}")
private Integer port;
@PostMapping("demo")
public String demo(@RequestBody User user){
return "hello" + user.toString()+"来自哪个服务器:"+port;
}
}
@Data
public class User {
private int id;
private String name;
}
3.3
<parent>
<groupId>com.yk</groupId>
<artifactId>cloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>springcloud-ribbon</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
- 配置
spring.application.name=spring-cloud-ribbon
server.port=8080
#连接Eureka Server
eureka.client.serviceUrl.defaultZone = http://localhost:801/eureka/
#显示IP和端口
eureka.instance.hostname = localhost
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id: ${spring.cloud.client.ip-address}:${server.port}
#服务提供方主机
service-provider.host = localhost
#服务提供方端口
service-provider.port = 9090
#服务提供方名称
service-provider.name = spring-cloud-service-provider
- 启动入口
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//@RibbonClient 单个定义
//多个定义
@RibbonClients({
@RibbonClient(name="spring-cloud-service-provider")
})
@EnableDiscoveryClient
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
//声明RestTemplate
//开启负载均衡的功能
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 实现服务的调用
@RestController
public class ClientController {
@Autowired
private RestTemplate restTemplate;
@Value("${service-provider.name}")
private String providerName;
@GetMapping("hello")
public String index(){
User user =new User();
user.setId(1);
user.setName("张三");
return restTemplate.postForObject("http://"+providerName+"/demo",user,String.class);
}
}
@Data
public class User {
private int id;
private String name;
}
3.4Demo演示
启动Eureka、ribbon、服务提供者(启动两个)