本文会使用到的注解有:@LoadBalanced,@RibbonClient,如果还不了解请自行去弄懂,本文只通过完整项目案例来阐述用法。
重点代码都在Ribbon服务器里,那我们来看看Ribbon项目的结构:
其中:
RibbonConfig、UserController、ServiceHiRibbonConfiguration对应的是user服务器的负载均衡。
RibbonConfig2、OrderController、ServiceHiRibbonConfiguration2对应的是user服务器的负载均衡。
让我们由下至上来讲解
最底下的是ServiceHiRibbonConfiguration和ServiceHiRibbonConfiguration2。
ServiceHiRibbonConfiguration:
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
@Configuration
public class ServiceHiRibbonConfiguration {
@Bean
public IRule hiRule() {
// user服务器的负载均衡采用轮询算法
return new RoundRobinRule();
}
}
ServiceHiRibbonConfiguration2:
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
@Configuration
public class ServiceHiRibbonConfiguration2 {
@Bean
public IRule hiRule() {
// order服务器的负载均衡采用随机算法
return new RandomRule();
}
}
注意:该配置类的包路径一定不能被@SpringBootApplication扫描到,原因自行百度。
可以看到,ServiceHiRibbonConfiguration和ServiceHiRibbonConfiguration2确定的是负载均衡算法,那么Ribbon怎么知道这两种算法分别对应哪个服务器呢,答案就在下面:
来看看RibbonConfig和RibbonConfig2,这两个类同样是配置类。
@Configuration
@RibbonClient(name = "user-service",configuration = ServiceHiRibbonConfiguration.class)
public class RibbonConfig {
}
@Configuration
@RibbonClient(name = "order-service",configuration = ServiceHiRibbonConfiguration2.class)
public class RibbonConfig2 {
}
这两个类只有配置作用,相当于配置文件,所以都是空的,重点在
@RibbonClient注解上。
@RibbonClient有两个参数
name:对应的服务的名字(在对应服务的yml或application文件中配置的)。
configuration:该服务对应的配置类。
所以可以看出来,就是这个注解将微服务和配置类关联了起来,实际上这个注解所在类只起到了“中间人”的作用。
那么上文所述就是多配置类和单配置类时的唯一区别了。
其实在单配置类(即只有一个微服务的情况下)的时候,@RibbonClient注解可以直接写在main方法所在的类上(也就是@SpringBootApplication所在的类上),而不需要新建一个配置类,然后再在这个类上添加@RibbonClient注解来达到配置文件的作用,如下:
@SpringBootApplication
@EnableDiscoveryClient
// 假设唯一的微服务是user
@RibbonClient(name = "user-service",configuration = ServiceHiRibbonConfiguration.class)
public class SpringcloudRibbonServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudRibbonServerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
再偷懒一点,在单微服务的情况下,甚至都不需要新建一个配置类用来指定负载均衡算法,直接在主类里写一个方法,附上@Bean注解即可,如下:
@SpringBootApplication
@EnableDiscoveryClient
public class SpringcloudRibbonServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudRibbonServerApplication.class, args);
}
@Bean
public IRule ribbonRule() {
return new RoundRobinRule(); // 采用轮询算法
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
不过实际上这种情况很少见,因为微服务肯定不止一个