使用idea创建maven项目

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.3.4.RELEASE</version>
  5. </parent>
  6. <properties>
  7. <spring.cloud-version>Hoxton.SR8</spring.cloud-version>
  8. </properties>
  9. <dependencyManagement>
  10. <dependencies>
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-dependencies</artifactId>
  14. <version>${spring.cloud-version}</version>
  15. <type>pom</type>
  16. <scope>import</scope>
  17. </dependency>
  18. </dependencies>
  19. </dependencyManagement>
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-security</artifactId>
  12. </dependency>
  1. server:
  2. port: 8900 #应用的端口号
  3. eureka:
  4. client:
  5. service-url:
  6. defaultZone: http://user:123@localhost:8900/eureka #eureka服务的的注册地址
  7. fetch-registry: false #是否去注册中心拉取其他服务地址
  8. register-with-eureka: false #是否注册到eureka
  9. spring:
  10. application:
  11. name: eureka-server #应用名称 还可以用eureka.instance.hostname = eureka-server
  12. security: #配置自定义Auth账号密码
  13. user:
  14. name: user
  15. password: 123
  1. @SpringBootApplication
  2. @EnableEurekaServer

在启动类中加入以下方法,防止spring的Auth拦截eureka请求

  1. @EnableWebSecurity
  2. static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Override
  4. protected void configure(HttpSecurity http) throws Exception {
  5. http.csrf().ignoringAntMatchers("/eureka/**");
  6. super.configure(http);
  7. }
  8. }
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  8. </dependency>
  1. server:
  2. port: 7900 #程序启动入口
  3. spring:
  4. application:
  5. name: provider-user #应用名称
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://user:123@${eureka.instance.hostname}:${server.port}/eureka/
  1. @SpringBootApplication
  2. @EnableEurekaClient

Controller相关代码如下:

  1. @RestController
  2. public class UserController {
  3. @GetMapping (value = "/user/{id}")
  4. public User getUser(@PathVariable Long id){
  5. User user = new User();
  6. user.setId(id);
  7. user.setDate(new Date());
  8. System.out.println("7900");
  9. return user;
  10. }
  11. @PostMapping (value = "/user")
  12. public User getPostUser(@RequestBody User user){
  13. return user;
  14. }
  15. }
  1. server:
  2. port: 8010
  3. spring:
  4. application:
  5. name: consumer-order
  6. eureka:
  7. client:
  8. serviceUrl:
  9. defaultZone: http://user:123@${eureka.instance.hostname}:${server.port}/eureka/
  1. @SpringBootApplication
  2. @EnableEurekaClient
  3. public class ConsumerApp
  4. {
  5. @Bean
  6. public RestTemplate restTemplate(){
  7. return new RestTemplate();
  8. }
  9. public static void main( String[] args )
  10. {
  11. SpringApplication.run(ConsumerApp.class,args);
  12. }
  13. }
  1. @RestController
  2. public class OrderController {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. @GetMapping (value = "/order/{id}")
  6. public User getOrder(@PathVariable Long id){
  7. //获取数据
  8. User user = new User();
  9. user.setId(id);
  10. user.setDate(new Date());
  11. user = restTemplate.getForObject("http://provider-user:7900/user/"+id,User.class);
  12. return user;
  13. }
  14. }

分别启动Eureka-server、provider-user、consumer-order三个服务

http://localhost:8900就可以看到两个服务已经注册到eureka注册中心上了

两个节点

  1. #高可用配置,两个节点
  2. spring:
  3. application:
  4. name: eureka-server-ha
  5. profiles:
  6. active: peer1
  7. eureka:
  8. client:
  9. serviceUrl:
  10. defaultZone: https://peer1/eureka/,http://peer2/eureka/
  11. ---
  12. server:
  13. port: 8901
  14. spring:
  15. profiles: peer1
  16. eureka:
  17. instance:
  18. hostname: peer1
  19. ---
  20. server:
  21. port: 8902
  22. spring:
  23. profiles: peer2
  24. eureka:
  25. instance:
  26. hostname: peer2

三个节点

  1. #高可用配置,三个
  2. spring:
  3. application:
  4. name: eureka-server-ha
  5. profiles:
  6. active: peer3
  7. eureka:
  8. client:
  9. serviceUrl:
  10. defaultZone: http://peer1:8901/eureka/,http://peer2:8902/eureka/,http://peer3:8903/eureka/
  11. ---
  12. spring:
  13. profiles: peer1
  14. eureka:
  15. instance:
  16. hostname: peer1
  17. server:
  18. port: 8901
  19. ---
  20. spring:
  21. profiles: peer2
  22. eureka:
  23. instance:
  24. hostname: peer2
  25. server:
  26. port: 8902
  27. ---
  28. spring:
  29. profiles: peer3
  30. eureka:
  31. instance:
  32. hostname: peer3
  33. server:
  34. port: 8903

轮询规则
在启动类中restTemplate()方法加入注解@LoadBalanced
RestTemplate 是由 Spring Web 模块提供的工具类,与 SpringCloud 无关,是独立存在的,因 SpringCloud 对 RestTemplate 进行了一定的扩展,所以 RestTemplate 具备了负载均衡的功能

  1. @Bean
  2. @LoadBalanced
  3. public RestTemplate restTemplate(){
  4. return new RestTemplate();
  5. }

在启动类上加注解

  1. @RibbonClient(name = "provider-user")

在application.yml中加入以下配置

  1. #使用配置文件方式实现负载均衡,优先级,配置文件>注解或java代码配置>cloud默认配置
  2. provider-user:
  3. ribbon:
  4. NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

自定义一个配置类,返回规则

  1. @RibbonClient(name = "provider-user",configuration = RibbonConfiguration.class)
  2. public class RibbonConfiguration {
  3. @Bean
  4. public IRule getRule(){
  5. return new RandomRule();
  6. }
  7. }

什么是feign,是声明式的webservice客户端,解决远程调用,支持JAX-RS,即RestFulWebService

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>
  1. @FeignClient("provider-user")
  2. public interface UserFeignClient {
  3. @RequestMapping (value = "/user/{id}", method = RequestMethod.GET)
  4. public User getUser(@PathVariable Long id);
  5. @RequestMapping (value = "/user", method = RequestMethod.POST)
  6. public User postUser(@RequestBody User user);
  7. }
  1. @Autowired
  2. private UserFeignClient userFeignClient;
  3. @GetMapping (value = "/user/{id}")
  4. public User getUser(@PathVariable Long id){
  5. //获取数据
  6. return this.userFeignClient.getUser(id);
  7. }
  8. @GetMapping (value = "/user")
  9. public User postUser(User user){
  10. return this.userFeignClient.postUser(user);
  11. }

hystrix是Netflix的一个类库,在微服务中,具有多层服务调用,主要实现断路器模式的类库

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  4. </dependency>
  1. @EnableCircuitBreaker
    1. 在Controller层类的方法上加注解,并编写退回方法,需同名
  1. @HystrixCommand(fallbackMethod = "findByIdFallBack")
  2. public User getOrder(@PathVariable Long id){
  3. //获取数据
  4. User user = new User();
  5. user.setId(id);
  6. user.setDate(new Date());
  7. user = restTemplate.getForObject("http://provider-user/user/"+id,User.class);
  8. System.out.println(Thread.currentThread().getId());
  9. return user;
  10. }
  11. public User findByIdFallBack(Long id){
  12. System.out.println(Thread.currentThread().getId());
  13. User user = new User();
  14. user.setId(1L);
  15. return user;
  16. }

actuator主要用于服务健康监控,springboot 1.X和2.x有所不同,本次为2.X

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-actuator</artifactId>
  4. </dependency>
  1. #健康监控配置
  2. management:
  3. endpoint:
  4. health:
  5. show-details: always #是否健康监控显示细节
  6. endpoints:
  7. web:
  8. exposure:
  9. include: hystrix.stream #hystrix保护机制,不直接暴露监控状态
  10. base-path: / #暴露的端点链接

1.X版本

  1. localhost:8080/health

2.X版本

  1. localhost:8080/actuator/health
  1. feign:
  2. hystrix:
  3. enabled: true # 总开关,可以通过java单独控制client
  1. @EnableFeignClients
  1. @RestController
  2. public class OrderFeignController {
  3. @Autowired
  4. private UserFeignClient userFeignClient;
  5. @Autowired
  6. private UserFeignNotHystrixClient userFeignNotHystrixClient;
  7. @GetMapping (value = "/order/{id}")
  8. public User getUser(@PathVariable Long id){
  9. //获取数据
  10. return userFeignClient.getUser(id);
  11. }
  12. /**
  13. * 测试Feign客户端单独控制
  14. * @param id
  15. * @return
  16. */
  17. @GetMapping(value = "/user/{id}")
  18. public User getUserNotHystrix(@PathVariable Long id){
  19. //获取数据
  20. return userFeignNotHystrixClient.getUserNotHystrix(id);
  21. }
  22. }

一个加了configuration一个没有,加了可以通过注解重写feignBuilder方法单独控制,默认是返回HystrixFeignBuilder

  1. @FeignClient(name = "provider-user", fallback = HystrixClientFallback.class)
  2. public interface UserFeignClient {
  3. @RequestMapping (value = "/user/{id}", method = RequestMethod.GET)
  4. User getUser(@PathVariable Long id);
  5. }
  6. @Component
  7. public class HystrixClientFallback implements UserFeignClient{
  8. @Override
  9. public User getUser(Long id) {
  10. System.out.println(Thread.currentThread().getId());
  11. User user = new User();
  12. user.setId(1L);
  13. return user;
  14. }
  15. }
  1. @FeignClient(name = "provider-user1",configuration = ConfigurationNotHystrix.class,fallback = HystrixClientNotHystrixFallback.class)
  2. public interface UserFeignNotHystrixClient {
  3. @RequestMapping (value = "/user/{id}", method = RequestMethod.GET)
  4. User getUserNotHystrix(@PathVariable Long id);
  5. }
  6. @Component
  7. public class HystrixClientNotHystrixFallback implements UserFeignNotHystrixClient{
  8. @Override
  9. public User getUserNotHystrix(Long id) {
  10. System.out.println(Thread.currentThread().getId());
  11. User user = new User();
  12. user.setId(1L);
  13. return user;
  14. }
  15. }
  1. @Configuration
  2. public class ConfigurationNotHystrix {
  3. @Bean
  4. @Scope("prototype")
  5. public Feign.Builder feignBuilder(){
  6. return Feign.builder();
  7. }
  8. }
  1. @FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
  2. protected interface HystrixClient {
  3. @RequestMapping(method = RequestMethod.GET, value = "/hello")
  4. Hello iFailSometimes();
  5. }
  6. @Component
  7. static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
  8. @Override
  9. public HystrixClient create(Throwable cause) {
  10. return new HystrixClient() {
  11. @Override
  12. public Hello iFailSometimes() {
  13. return new Hello("fallback; reason was: " + cause.getMessage());
  14. }
  15. };
  16. }
  17. }

版权声明:本文为uhande原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/uhande/p/13787628.html