SpringCloud之Ribbon-負載均衡

負載均衡:Spring Cloud Ribbon

Spring Cloud Ribbon 是一個基於Http和TCP的客服端負載均衡工具,它是基於Netflix Ribbon實現的。通過SpringCloud的自動配置使得項目可以自動的給RestTemplate添加攔截器,實現負載均衡的作用。

快速入門

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mask</groupId>
  <artifactId>cloud</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>


  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.5.RELEASE</version>
  </parent>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Greenwich.SR1</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

  </dependencies>
</project>
  • application.properties
server.port=8080
#server.port=8088
USER-SERVICE.ribbon.listOfServers=localhost:8080,localhost:8088
USER-SERVICE.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  • UserController
@RestController
@RequestMapping("manager")
public class UserController {
	@RequestMapping(value="user/{id}",method = {RequestMethod.GET})
	public User queyUserById(@PathVariable(value = "id") Integer id){
		System.out.println("-------getUser--------");
		return new User("張三", new Date(), true, 12345.00);
	}

	@RequestMapping(value="user",method = {RequestMethod.POST})
	public User saveUser(@RequestBody User user){
		System.out.println("-------saveUser--------");
		return user;
	}

	@RequestMapping(value="user",method = {RequestMethod.PUT})
	public void update(@RequestBody User user){
		System.out.println("-------updateUser--------");
	}

	@RequestMapping(value="user/{pageNow}/{pageSize}",method = {RequestMethod.GET})
	public List<User> queyUserByPage(@PathVariable(value = "pageNow") Integer pageNow,
									 @PathVariable(value = "pageSize") Integer pageSize){
		List<User> list = new ArrayList<>();
		list.add(new User("張三", new Date(), false, 11111.00));
		list.add(new User("李四", new Date(), true, 20000.00));
		System.out.println("-------getUserPage--------");
		return list;
	}

	@RequestMapping(value="user/{ids}",method = {RequestMethod.DELETE})
	public void deleteUserById(@PathVariable(value = "ids") Integer[] ids){
		System.out.println("-------deleteUsers--------");
	}
}
  • SpringRibbonApplication
@SpringBootApplication
public class SpringRibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringRibbonApplication.class,args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • User
public class User implements Serializable {
    private Integer id;
    private String name;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birthDay;
    private Boolean sex;
    private Double salary;
}
  • RestTemplateTests
@SpringBootTest(classes = SpringRibbonApplication.class)
@RunWith(SpringRunner.class)
public class RestTemplateTests {
	@Autowired
	private RestTemplate restTemplate;
	@Test
	public void testQueryUserById(){
		String url="http://USER-SERVICE/manager/user/1";
		User user = restTemplate.getForObject(url, User.class);
		System.out.println(user);
	}
	@Test
	public void testQueryUserByPage(){
		String url="http://USER-SERVICE/manager/user/1/10";
		List<User> users = restTemplate.getForObject(url, List.class);
		for (int i = 0; i < users.size(); i++) {
			System.out.println(users.get(i));
		}
	}
	@Test
	public void testSaveUser(){
		String url="http://USER-SERVICE/manager/user";
		User user = restTemplate.postForObject(url, new User("李四", new Date(), true, 15000.0), User.class);
		System.out.println(user);
	}
	@Test
	public void testUpdateUser(){
		String url="http://USER-SERVICE/manager/user";
		User user = new User("李四", new Date(), true, 18000.0);
		user.setId(3);
		restTemplate.put(url,user);
	}
	@Test
	public void testDeleteUser(){
		String url="http://USER-SERVICE/manager/user/1,2,3";
		restTemplate.delete(url);
	}
}

除此自外,SpringCloud提供了一種基於配置文件的配置方式

  • SpringRibbonApplication
@SpringBootApplication
@RibbonClient(name = "USER-SERVICE",configuration = {UserSerivceRibbonConfigure.class})
public class SpringRibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringRibbonApplication.class,args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • UserSerivceRibbonConfigure
@Configuration
public class UserSerivceRibbonConfigure {
    @Bean
    public ServerList<Server> ribbonServerList(){
        Server server1 = new Server("localhost", 8080);
        server1.setZone("beijing");

        Server server2 = new Server("localhost", 9090);
        server2.setZone("shanghai");
        return new StaticServerList<Server>(server1,server2);
    }

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
    @Bean
    public ZonePreferenceServerListFilter ribbonServerListFilter(){
        ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
        filter.setZone("beijing");
        return filter;
    }
}

用戶可以直接使用LoadBalancerClient查詢服務列表

@Autowired
private LoadBalancerClient loadBalancer;

@Test
public void testChoose(){
  for (Integer i=0;i<10;i++){
    ServiceInstance instance = loadBalancer.choose("stores");
    URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
    System.out.println(storesUri);
  }
}

測試結果
在這裏插入圖片描述
在這裏插入圖片描述

發佈了15 篇原創文章 · 獲贊 7 · 訪問量 3868
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章