程序結構:
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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.zyu</groupId> <artifactId>consumer_service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>consumer_service</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <!--SpringCloud所有依賴管理的坐標--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
方式一
在springboot主程序掃描的包外定義配置類,然后為springboot主程序添加 @RibbonClient 注解引入配置類。
Springboot 主程序:
package com.zyu; import com.ribbonconfig.MySelfRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication //該注解表明應用既作為eureka實例又為eureka client 可以發現注冊的服務 @EnableDiscoveryClient //在啟動該微服務的時候就能去加載我們的自定義Ribbon配置類,從而使配置生效 @RibbonClient(value = "user-service", configuration = {MySelfRule.class}) public class ConsumerServiceApplication { public static void main(String[] args) { SpringApplication.run(ConsumerServiceApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
Rule配置文件類,配置類不應該在SpringBoot的包路徑下,通過@RibbonClient 注解加載:
package com.ribbonconfig; import com.netflix.loadbalancer.IRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MySelfRule { @Bean public IRule getIRule() { /** * 修改Ribbon 負載均衡策略 */ //return new RandomRule(); //默認輪詢,自定義為隨機 /** * 自定義 Ribbon 負載均衡策略 */ return new MyRule(); } }
自定義LoadBalance:
package com.ribbonconfig; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.*; import java.util.List; import java.util.Random; public class MyRule extends AbstractLoadBalancerRule { /** * 服務選擇算法,隨機調用 * @param lb * @param o * @return */ public Server choose(ILoadBalancer lb, Object o) { // 獲取服務器列表 List<Server> servers = lb.getAllServers(); // 生產隨機數 Random r = new Random(); int rand = r.nextInt(10); System.out.println("隨機數: " + rand); if(rand > 7){ return getServerByPort(servers, 9091); } else if (rand > 3) { return getServerByPort(servers, 9092); }else{ return getServerByPort(servers, 9093); } } /** * 根據傳入的端口號,返回服務對象 * @param servers * @param port * @return */ private Server getServerByPort(List<Server> servers, int port){ for(Server s : servers){ if(s.getPort() == port){ return s; } } return null; } @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } @Override public Server choose(Object o) { return choose(getLoadBalancer(), o); } }
方式二
application.yml文件配置方式
#@RibbonClient(name = "user-service") 與name相同,表示針對該微服務使用自定義負載均衡規則
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.ribbonconfig.MyRule
配置的優先級
配置文件的優先級 > java代碼的配置方式 > netflix自定義的配置方式