1、什么是负载均衡
** ribbon是基于netflix ribbon实现的一个工作在consumer端的负载均衡工具,提供了很多负载均衡策略:轮询、随机 **
2、ribbon入门
1)创建服务提供者ribbon_provider
pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
service
package com.bjpoernode.service;
import com.bjpowernode.pojo.User;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
@Override
public User getUserById(Integer id) {
return new User(id,"王粪堆1",18);//另外一个可以设置为王粪堆2以便观察负载均衡
}
}
contrller
package com.bjpoernode.controller;
import com.bjpoernode.service.UserService;
import com.bjpowernode.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired
private UserService userService;
@RequestMapping("/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
}
}
app
package com.bjpoernode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class);
}
}
将ribbon_provider再复制一份来测试负载均衡
两个项目的application.yml分别为
server:
port: 9090
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848
application:
name: ribbon-provider
server:
port: 9091
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.209.129:8848
application:
name: ribbon-provider
2)创建服务消费者ribbon_consumer:
pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.bjpowernode</groupId>
<artifactId>springcloud_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
config
package com.bjpowernode.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {
@Bean
/**
* 1.在RestTemplate上添加@LoadBalanced后,ribbon会给RestTemplate的请求添加拦截器
* 2.在拦截器中根据serverId获得List<Service>,然后再使用ribbon的负载均衡算法从
* List<Service>获得 一个service
* 3.最后再把serverId换成ip和端口
*/
@LoadBalanced //开启ribbon负载均衡,默认是轮询策略
public RestTemplate restTemplate(){
return new RestTemplate();
}
//随机策略
@Bean
public IRule iRule(){
return new RandomRule();
}
}
contrller
package com.bjpowernode.controller;
import com.bjpowernode.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
private int currentIndex;
@RequestMapping(value = "/getUserById/{id}")
public User getUserById(@PathVariable Integer id){
//获取nacos中注册的指定服务信息
/* List<ServiceInstance> serviceList
= discoveryClient.getInstances("ribbon-provider");
//随机方式获得服务
// currentIndex = new Random().nextInt(serviceList.size());
轮询方式获得服务
currentIndex = (currentIndex + 1) % serviceList.size();
ServiceInstance instance = serviceList.get(currentIndex);
//调用服务
String url="http://"+ instance.getHost() +":"+ instance.getPort() +"provider/getUserById/"+id;*/
//不使用ribbon:ip:port
//String serviceUrl = "127.0.0.1:9090";
//使用ribbon:不再使用ip:port的方式,而是改成了serviceId(即Nacos中注册的服务名称)
String url = "http://ribbon-provider/provider/getUserById/"+id;
return restTemplate.getForObject(url, User.class);
}
}
app
package com.bjpowernode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class);
}
}
application.yml
server:
port: 8080
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.10.135:8848 #nacos服务的地址
application:
name: ribbon-consumer #向注册中心注册的名字