SpringCloud微服务

SpringCloud微服务入门


一.什么是SpringCloud

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等。Spring Cloud 并不重复造轮子,而是将市面上开发得比较好的模块集成进去,进行封装,从而减少了各模块的开发成本。

二.SpringCloud的基础功能

  • 服务发现:Netflix Eureka
  • 客户端负载均衡:Netflix Ribbon
  • 断路器:Netflix Hystrix
  • 服务网关:Netflix Zuul
  • 声明式服务调用:Netflix Feign
  • 分布式配置:Spring Cloud Config

三.SpringCloud引入Eureka

Spirng Cloud Eureka使用Netflix Eureka来实现服务注册与发现,由两个组件组成:Eureka服务端(Eureka Service)和Eureka客户端(Eureka Client)。而Eureka Client又分为服务提供者和服务消费者。

  1. 在项目中加入Eureka服务中心的依赖

    <!--  Eureka服务中心  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  2. 写yml配置文件

    server:
      port: 7070
    spring:
      application:
        name: eureka-service
    eureka:
      client:
        service-url:
        	#该注册中心指向另一个注册中心 互相注册。可配置多个 使用“,”分割
          defaultZone: http://127.0.0.1:7070/eureka 
          #是否检索服务
          fetch-registry: false 
          #是否向服务注册中心注册自己
          register-with-eureka: false 
      instance:
        #开启后显示服务器地址
        prefer-ip-address: true
        ip-address: 127.0.0.1
    
  3. 在主启动类上加注解

    @SpringBootApplication
    @EnableEurekaServer //将项目作为SpringCloud中的注册中心
    public class EurekaMain7070 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaMain7070.class,args);
        }
    }
    
  4. 将其他服务注册到Eureka注册中心

     <!--  Eureka客户中心  -->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
    
    server:
      port: 8080
    spring:
      application:
        name: user-service
    eureka:
      client:
      	#表示向注册中心注册自己 默认为true
        register-with-eureka: true 
        #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetch-registry: true 
        service-url:
          defaultZone: http://127.0.0.1:7070/eureka #入驻地址
    
    @SpringBootApplication
    @EnableEurekaClient  //让注册中心能够发现
    public class UserMain8080 {
        public static void main(String[] args) {
            SpringApplication.run(UserMain8080.class,args);
        }
    }
    

3.1 Eureka的治理机制

  1. 服务提供者
    • 服务注册:启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息
    • 服务续约:在注册完服务之后,服务提供者会维护一个心跳用来持续告诉Eureka Server: "我还活着 ”
    • 服务下线:当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server, 告诉服务注册中心:“我要下线了 ”
  2. 服务消费者
    • 获取服务:当我们启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单
    • 服务调用:服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。在进行服务调用的时候,优先访问同处一个Zone中的服务提供方。
  3. 服务注册中心
    • 失效剔除:默认每隔一段时间(默认为60秒) 将当前清单中超时(默认为90秒)没有续约的服务剔除出去
    • 自我保护:EurekaServer 在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%(通常由于网络不稳定导致)。 Eureka Server会将当前的实例注册信息保护起来, 让这些实例不会过期,尽可能保护这些注册信息

四.SpringCloud引入Ribbon

Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的。它不像spring cloud服务注册中心、配置中心、API网关那样独立部署,但是它几乎存在于每个spring cloud 微服务中。包括feign提供的声明式服务调用也是基于该Ribbon实现的。ribbon提供很多种负载均衡算法(默认的负载均衡策略是轮询),例如 轮询、随机、最少并发策略等等。甚至包含自定义的负载均衡算法。

  1. 在项目中加入Ribbon依赖

     <!--  ribbon负载均衡  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    
  2. 在yml配置文件中配置Ribbon负载均衡策略

    provider-service:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    
  3. 在主启动类开启负载均衡

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
      return new RestTemplate();
    }
    
  4. 进行测试

    @RestController
    @RequestMapping("user")
    public class UserController {
       @Resource
       private UserService userService;
       @GetMapping("getUserById/{id}")
        public User getUserById(@PathVariable("id") Integer id){
            return userService.getUserById(id);
        }
    }
    
    @Service
    public class UserServiceImpl implements UserService {
        @Resource
        private RestTemplate restTemplate;
        @Override
        public User getUserById(Integer id) {
           String url = "http://provider-service/user/getUserById/";
           return restTemplate.getForObject(url+id,User.class);
        }
    }
    

    多次刷新看到调用的端口在来回切换则成功实现负载均衡

五.SpringCloud引入Hystrix

在高并发的情况下,由于单个服务的延迟,可能导致所有的请求都处于延迟状态,甚至在几秒钟就使服务处于负载饱和的状态,资源耗尽,直到不可用,最终导致这个分布式系统都不可用,这就是“雪崩”。Hystrix断路器可以防止一个应用程序多次试图执行一个操作,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延

  1. 在消费者pom中加入Hystrix的依赖包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  2. 在主启动类加入注解

    @EnableHystrix
    
  3. 测试是否生效

    @Override
    @HystrixCommand(fallbackMethod = "queryUserByIdFallback",  //失败后的回调函数
    //每十次请求中失败率达到百分之三十则开启熔断,此时再调用该服务,则直接返回失败,直到十秒后重新检测该触发条件,判断是否把熔断器打开或者继续关闭
                    commandProperties = {
                    @HystrixProperty(name="circuitBreaker.requestVolumeThreshold" ,value="10"),
                    @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds" ,value="10000"),
                    @HystrixProperty(name="circuitBreaker.errorThresholdPercentage" ,value="30")
            })
    public User queryUserById(Integer id) {
        long begin = System.currentTimeMillis();
        User user= restTemplate.getForObject(url+id, User.class);
        long end = System.currentTimeMillis();
        logger.info("访问用时{}",end-begin);
        return user;
    }
    
    private User queryUserByIdFallback(Integer id){
        User user = new User();
        user.setId(id);
        user.setUserCode("查询用户信息出现异常");
        return user;
    }
    

六.SpringCloud引入Feign

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。

  1. 在服务调用者pom加入Feign依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 在yml写配置文件

    feign:
      hystrix:
        enabled: true  #开启Feign Hystrix 支持
      httpclient:
        enabled: false #关闭httpclient
      okhttp:
        enabled: true  #开启okHttp
    
  3. 在主启动类加入注解

    @EnableFeignClients
    
  4. 使用Feign实现远程调用

    /**
    * value:指定调用哪个服务
    * fallbackFactory:熔断器的降级提示
    */
    @FeignClient(value = "provider-service",fallback = UserFeignClientFallback.class)
    public interface UserFeignClient {
        //采用Feign我们可以使用SpringMVC的注解来对服务进行绑定!
        @GetMapping("/user/getUserById/{id}")
        User userFeign(@PathVariable("id") Integer id);
    }
    
    /**
     * Feign中使用断路器
     * 这里主要是处理异常出错的情况(降级/熔断时服务不可用,fallback就会找到这里来)
     */
    @Component
    public class UserFeignClientFallback implements UserFeignClient {
        @Override
        public User userFeign(Integer id) {
            User user = new User();
            user.setId(id);
            user.setUserCode("查询用户信息出现异常");
            return user;
        }
    }
    
    @RestController
    @RequestMapping("user")
    public class UserController {
        @Resource
        private UserFeignClient userFeignClient;
      
        @GetMapping("feign/{id}")
        public User userFeign(@PathVariable("id") Integer id){
            return userFeignClient.userFeign(id);
        }
    }
    

七.SpringCloud引入Zuul

Zuul是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul相当于是设备和Netflix流应用的 Web 网站后端所有请求的前门。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得

Zuul包含了对请求的路由和过滤两个最主要的功能:路由转发:接收一切外界请求,转发到后端的微服务上去。过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成,路由转发也是通过过滤器实现的

  1. 新建项目在pom中加入依赖

     <!--  Zuul网关  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    <!--  Eureka客户中心  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 编写yml配置文件

    server:
      port: 10080
    spring:
      application:
       #服务的名称
        name: zuul-service
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:9090/eureka #指定注册中心地址
    zuul:
      retryable: true
      ignored-services:
        - provider-service  #忽略整个服务,对外提供接口
    
  3. 编写主启动类

    @SpringBootApplication
    @EnableZuulProxy
    public class ZuulMain10080 {
        public static void main(String[] args) {
            SpringApplication.run(ZuulMain10080.class);
        }
    }
    
  4. 自定义过滤器

    @Component
    public class LoginFilter extends ZuulFilter {
      /**
         * 返回字符串,代表过滤器的类型。包含以下4种:
         * pre:请求在被路由之前执行
         * routing:在路由请求时调用
         * post:在routing和error过滤器之后调用
         * error:处理请求时发生错误调用
        */
        @Override
        public String filterType() {
            return "pre";
        }
        //通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
        @Override
        public int filterOrder() {
            return 0;
        }
       //返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
        @Override
        public boolean shouldFilter() {
            return true;
        }
      	//过滤器的具体业务逻辑。
        @Override
       public Object run() throws ZuulException {
            // 登录校验逻辑。
            // 1)获取Zuul提供的请求上下文对象
            RequestContext ctx = RequestContext.getCurrentContext();
            // 2) 从上下文中获取request对象
            HttpServletRequest req = ctx.getRequest();
            // 3) 从请求中获取token
            String token = req.getParameter("access-token");
            // 4) 判断
            if(token == null || "".equals(token.trim())){
                // 没有token,登录校验失败,拦截
                ctx.setSendZuulResponse(false);
                // 返回401状态码。也可以考虑重定向到登录页。
                ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            }
            // 校验通过,可以考虑把用户信息放入上下文,继续向后执行
            return null;
        }
    }
    

八.SpringCloud Config

随着业务的扩展,我们的服务会越来越多,越来越多。每个服务都有自己的配置文件。既然是配置文件,给我们配置的东西,那难免会有些改动的。

Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

简单来说,使用Spring Cloud Config就是将配置文件放到统一的位置管理(比如GitHub),客户端通过接口去获取这些配置文件。在GitHub上修改了某个配置文件,应用加载的就是修改后的配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值