• springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig


    原文地址:http://blog.csdn.net/yp090416/article/details/78017552

    springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig

    相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展。会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新建的项目都是用springboot,附源码下载。

    coding仓库地址: coding地址 csdn下载地址: csdn下载地址

    如果有问题请在下边评论,或者200909980加群交流。

    Eureka:服务发现
    Hystrix:断路器
    Zuul:智能路由
    Ribbon:客户端负载均衡
    Turbine:集群监控
    Springcloud-config:远程获取配置文件

    这里写图片描述

    接下来,我们开始搭建项目,首先我们到spring为我们提供的一个网站快速搭建springboot项目,点击访问,我这里用的是gradle,如果各位客官喜欢用maven,好吧你可以到http://mvnrepository.com/查看对应的依赖,点我访问

    一、搭建eureka-server服务springcloud-eureka-server

    eureka-server作为服务发现的核心,第一个搭建,后面的服务都要注册到eureka-server上,意思是告诉eureka-server自己的服务地址是啥。当然还可以用zookeeper或者springconsul。

    这里写图片描述

    • 1.修改build.gradle文件

    如果是maven项目请对应的修改pom.xml

    //加入阿里的私服仓库地址
    maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
    • 1
    • 2
    //加入依赖  
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka-server', version: '1.3.4.RELEASE'
    //加入security,是因为访问eureka-server需要用户名和密码访问,为了安全
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '1.5.6.RELEASE'
    • 1
    • 2
    • 3
    • 4

    还有几点需要修改的,大家对应图片看看,就是springboot打包的时候会提示找不到主累。
    这里写图片描述

    • 2.修改 application.yml,建议用yml。
    server:
      port: 8761
    eureka:
      datacenter: trmap
      environment: product
      client:
        healthcheck:
          enabled: true
        service-url:
          defaultZone: http://root:booszy@localhost:8761/eureka
        register-with-eureka: false #关闭自己作为客户端注册
        fetch-registry: false
    security:
      basic:
        enabled: true
      user:
        name: root #用户名和密码,等会访问的时候,会要求你登录,服务注册的时候也需要带着用户名和密码
        password: booszy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 3.修改程序的主类,建议修改类名,要加如eureka的 @EnableEurekaServer 注解,然后运行main方法。
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServerApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里写图片描述

    http://localhost:8761/ 这个是eureka-server的页面地址,到这里,说明eureka-server搭建好了,简单吧,这一步一定要成功,否则后面的就不能继续进行下去了,后边基本类似。

    二、搭建config-server服务springcloud-config-server

    springcloud-config-server是用来将远程git仓库的配置文件动态拉下来,这样配置文件就可以动态的维护了。

    新建一个springboot项目,修改maven私服地址,并加入一下依赖。

    • 1.修改build.gradle文件
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.3.4.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-config-server', version: '1.3.2.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: '1.5.6.RELEASE'
    //连接config-server也需要用户名和密码
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '1.5.6.RELEASE'
    • 1
    • 2
    • 3
    • 4
    • 5
    • 2.修改application.yml文件
    server:
      port: 8500
    eureka:
      client:
        service-url:
          #注册服务到eureka上,记住这里要加上eureka-server的用户名和密码
          defaultZone: http://root:booszy@localhost:8761/eureka
      instance:
        prefer-ip-address: true
        #可能比较长,复制的时候请写在一行
        instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
        appname: springcloud-config-server
    spring:
      application:
        name: springcloud-config-server
      cloud:
        config:
          server:
            git:
              #这是其他项目配置文件的git仓库地址
              uri: https://git.coding.net/yirenyishi/springcloud-config-profile
              searchPaths: '{application}'
    security:
      basic:
        enabled: true
      user:
        #这是config-server的用户名和密码
        name: root
        password: booszy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 3.修改启动类

    修改启动类,要加入这三个注解,因为要注册到eureka-server上,所以需要@EnableEurekaClient这个注解

    @SpringBootApplication
    @EnableConfigServer
    @EnableEurekaClient
    public class ConfigServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    然后运行启动springboot项目,等启动成功后访问eureka的页面,会发现springcloud-config-server已经注册到上面了,如果启动报错,请检查错误信息。

    这里写图片描述

    三、搭建服务提供者服务springcloud-provider-config

    编写一个服务提供者,提供两个接口,即获取单个用户的信息和获取一个用户列表。用到了spring-data-jpa 和 spring-webmvc ,当然你们公司用什么你还是继续用什么。

      • 注意 : 这里除了application.xml,还需要一个bootstrap.yml*
      1. 修改build.gradle文件
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("com.alibaba:druid-spring-boot-starter:1.1.2")
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.3.4.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: '1.5.6.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-config', version: '1.3.2.RELEASE'
    compile group: 'org.springframework.session', name: 'spring-session-data-redis', version: '1.3.1.RELEASE'
    runtime('mysql:mysql-connector-java')
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 2.编写配置文件bootstrap.yml

    * 注意 : 这里除了application.xml,还需要一个bootstrap.yml

    application.xml我是放到远程仓库地址的,大家可以直接到我的远程仓库,根据项目名(springcloud-provider-config)查询。配置文件的仓库地址:点击访问

    spring:
      application:
        name: springcloud-provider-config
      cloud:
        config:
          #config-server的配置,不需要硬编码config-server的地址,使用service-id去eureka-server获取cong-server的地址
          discovery:
            enabled: true
            service-id: springcloud-config-server
          fail-fast: true
          username: root
          password: booszy
          profile: dev
    eureka:
      client:
        service-url:
          defaultZone: http://root:booszy@localhost:8761/eureka
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
        appname: springcloud-provider-config
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 3.编写代码

    编写主类

    @SpringBootApplication
    @EnableEurekaClient
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    新建UserController, 考虑篇幅 UserService 和 UserRepository就不贴代码了,想看的可以下载我的代码。

    @RequestMapping("user")
    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        /**
         * @param id
         * @return
         */
        @GetMapping("{id}")
        public User getuser(@PathVariable String id) {
            User user = null;
            try {
                System.out.println(id);
                user = userService.find(id);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return user;
        }
    
        /**
         * @return
         */
        @GetMapping("list")
        public List<User> users() {
            try {
                List<User> user = userService.findAll();
                if (user != null && user.size() != 0) {
                    return user;
                }
                return null;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    运行springboot项目,去eureka-server查看,有没有注册上。

    这里写图片描述

    我们的springcloud-provider-config已经注册到eureka上了,访问接口,成功。

    这里写图片描述

    四、搭建消费者服务springcloud-consumer-config-swagger

    消费者要访问服务提供者的服务,这里用的是通过RestTemplate请求resetful接口,使用ribbon做客户端负载均衡,hystrix做错误处理,swagger生成接口文档。
    还是熟悉的配方,熟悉的味道,新建springboot项目,添加项目依赖。

    • 1.修改build.gradle文件
    compile('org.springframework.boot:spring-boot-starter-web')
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.3.4.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: '1.5.6.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-config', version: '1.3.2.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-hystrix', version: '1.3.4.RELEASE'
    compile(
        "io.springfox:springfox-swagger2:2.7.0",
        "io.springfox:springfox-swagger-ui:2.7.0"
    )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 2.修改bootstrap.yml文件

    application.yml 在git仓库,请前往git仓库查看。

    spring:
      application:
        name: springcloud-consumer-config
      cloud:
        config:
          discovery:
            enabled: true
            service-id: springcloud-config-server
          fail-fast: true
          username: root
          password: booszy
          profile: dev
    eureka:
      client:
        service-url:
          defaultZone: http://root:booszy@localhost:8761/eureka
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
        appname: springcloud-consumer-config
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 3.编写代码

    启动类代码

    @RibbonClient 指定服务使用的负载均衡类型,name不指定服务则为所有的服务打开负载均衡,也可以在用yml中进行配置。
    @EnableHystrix 是支持hystrix打开断路器,在规定时间内失败参数超过一定参数,就会打开断路器,不会发起请求,而是直接进入到错误处理方法。

    @SpringBootApplication
    @EnableEurekaClient
    @RibbonClient(name = "springcloud-provider-config", configuration = RibbonConfiguration.class)
    @ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExtendRibbon.class)})
    @EnableHystrix
    public class ConsumerApplication {
        @Autowired
        private RestTemplateBuilder builder;
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return builder.build();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    新建UserController

    ribbon一个坑,不能接受List类型,要使用数组接收。
    @Api xxx 是swagger的注解
    @HystrixCommand(fallbackMethod=”userFallbackMethod”)
    如果请求失败,会进入userFallbackMethod这个方法,userFallbackMethod这个方法要求参数和返回值与回调他的方法保持一致。

    ribbon这个方法就是通过service-id获取获取服务实际的地址,这样服务的地址就不用硬编码了。

    @Api("springcloud consumer user 控制器")
    @RequestMapping("user")
    @RestController
    public class UserController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        /**
         * @param id
         * @return
         */
        @ApiOperation(value = "根据用户id查询用户信息", httpMethod = "GET", produces = "application/json")
        @ApiResponse(code = 200, message = "success", response = User.class)
        @GetMapping("{id}")
        @HystrixCommand(fallbackMethod="userFallbackMethod")
        public User getUser(@ApiParam(name = "id", required = true, value = "用户Id") @PathVariable String id) {
            return this.restTemplate.getForObject("http://springcloud-provider-config/user/" + id, User.class);
        }
    
        public User userFallbackMethod(String id){
            return null;
        }
    
        /**
         * 这块ribbon不支持复杂数据类型list,所以要用数组接受,然后转list
         * @return
         */
        @GetMapping("list")
        @HystrixCommand(fallbackMethod = "userList")
        public List<User> users(HttpServletRequest request) {
            try {
                User[] forObject = this.restTemplate.getForObject("http://springcloud-provider-config/user/list", User[].class);
                List<User> users = Arrays.asList(forObject);
                return users == null ? new ArrayList<User>() : users;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public List<User> userList(HttpServletRequest request) {
            return null;
        }
    
        /**
         * 通过服务id获取服务的地址
         * @return
         */
        @GetMapping("ribbon")
        public String ribbon(){
            ServiceInstance serviceInstance = loadBalancerClient.choose("springcloud-provider-config");
            return serviceInstance.getUri().toString();
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    运行springboot项目,先看有没有注册到eureka-server上。

    这里写图片描述

    注册成功后,访问接口,测试是否正确。

    这里写图片描述

    测试swagger-ui,访问localhost:8200/swagger-ui.html

    这里写图片描述

    到这里消费者服务就算是完成了,后边大家自己进行扩展。

    五、用zuul做路由转发和负载均衡

    这些微服务都是隐藏在后端的,用户是看不到,或者不是直接接触,可以用nginx或者zuul进行路由转发和负载均衡,zuul负载均衡默认用的是ribbon。

    • 1.修改build.gradle文件
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka', version: '1.3.4.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-zuul', version: '1.3.4.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-actuator', version: '1.5.6.RELEASE'
    compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-config', version: '1.3.2.RELEASE'
    • 1
    • 2
    • 3
    • 4
    • 2.修改bootstrap.yml

    还是原来的配方,application.yml在git仓库

    spring:
      application:
        name: springcloud-zuul
      cloud:
        config:
          discovery:
            enabled: true
            service-id: springcloud-config-server
          fail-fast: true
          username: root
          password: booszy
          profile: dev
    eureka:
      client:
        service-url:
          defaultZone: http://root:booszy@localhost:8761/eureka
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
        appname: springcloud-zuul
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 3.启动类

    @RefreshScope这个注解是当application.yml配置文件发生变化的时候,不需要手动的进行重启,调用localhost:8400/refresh,就会加载新的配置文件,当然正在访问的客户并不影响还是使用旧的配置文件,因为不是重启,后来的用户会使用新的配置文件。注意这块的刷新要用post请求

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    @RefreshScope
    public class ZuulApplication {
        public static void main(String[] args) {
            SpringApplication.run(ZuulApplication.class, args);
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    启动springboot项目,访问eureka-server

    这里写图片描述

    这时候,我们就要通过zuul访问微服务了,而不是直接去访问微服务。
    应该访问地址http://192.168.89.89:8400/springcloud-consumer-config/user/list,这块你要换成你的zuul地址。

    但是有些人就会说,这样以后用户请求会不会太长,比较反感,所以可以通过配置进行修改访问地址。

    zuul:
      routes:
        springcloud-consumer-config: /consumer/**
        springcloud-provider-config: /provider/**
    • 1
    • 2
    • 3
    • 4

    在application.yml中加入这样一段配置,其实就是nginx中的反向代理,使用一下简短的可以代理这个微服务。这个时候我们就可以这样去访问了http://192.168.89.89:8400/consumer/user/list,是不是简短了很多

    这里写图片描述

  • 相关阅读:
    妹妹
    小猴和北极熊
    盛趣->盛大
    运维
    操之过急
    修马路
    博人传
    醉酒
    【跨域】SpringBoot跨域,拦截器中,第一次获取的请求头为NULL,发送两次请求的处理方式
    【Linux】Linux安装Tomcat
  • 原文地址:https://www.cnblogs.com/wlzjdm/p/7811536.html
Copyright © 2020-2023  润新知