精华内容
下载资源
问答
  • SpringCloud五大组件

    万次阅读 多人点赞 2019-12-30 22:53:23
    SpringCloud五大组件 五大组件:Eureka(注册中心), ​ Ribbon/Feign(负载均衡), ​ Zuul(网关), ​ Config(配置中心), ​ Hystrix(熔断器) 注:本文章较长,但是五大组件全都包含 新建一个父模块,导包,...

    SpringCloud五大组件

    五大组件:Eureka(注册中心),

    Ribbon/Feign(负载均衡),

    Zuul(网关),

    Config(配置中心),

    Hystrix(熔断器)

    注:本文章较长,但是五大组件全都包含

    新建一个父模块,导包,包含SpringCloud以及SpringBoot的包

    1.Eureka------注册中心

    ​ 1.1在SpringCloud官网 找到Eureka(How to includ Eureka)

    ​ 1.2新建模块Eureka,导包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    

    ​ 1.3application.yml

    server:
      port: 1000
    eureka:
      instance:
        hostname: localhost #主机
      client:
        registerWithEureka: false #禁止注册中心向自己注册
        fetchRegistry: false #禁止注册中心拉取注册地址清单
        serviceUrl: #微服务向注册中心注册的地址
          defaultZone: http://localhost:1000/eureka/
    
    
    

    1.4在主配置类上打标签 @EnableEurekaServer 开启Eureka事务

    package cn.itsource.springboot;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaApplication {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(EurekaApplication.class).web(true).run(args);
        }
    
    }
    

    2.EurekaServer高可用集群

    ​ 2.1为什么使用Eureka高可用集群?

    ​ 答:当只有一个EurekaServer,如果挂掉了,那么整个微服务都不可用,所以要进行集群

    ​ 2.2

    在“我的电脑”C:\Windows\System32\drivers\etc这个路径下 添加两个peer1和peer2
    

    ​ 127.0.0.1 peer1
    ​ 127.0.0.1 peer2

    ​ 2.3 application.yml配置如下

    spring:
      profiles:
        active: peer1
    ---
    server:
      port: 1000
    eureka:
      instance:
        hostname: peer1 #主机
      client:
        registerWithEureka: false #禁止注册中心向自己注册
        fetchRegistry: false #禁止注册中心拉取注册地址清单
        serviceUrl: #微服务向注册中心注册的地址
          defaultZone: http://peer2:1001/eureka/
    spring:
      profiles: peer1
    ---
    server:
      port: 1001
    eureka:
      instance:
        hostname: peer2 #主机
      client:
        registerWithEureka: false #禁止注册中心向自己注册
        fetchRegistry: false #禁止注册中心拉取注册地址清单
        serviceUrl: #微服务向注册中心注册的地址
          defaultZone: http://peer1:1000/eureka/
    spring:
      profiles: peer2
    

    3.Ribbon

    ribbon是负载均衡器,是基于RestTemplate ,它赋予了RestTemplate 负载均衡的能力

    在客户端order中使用Ribbon

    3.1导入jar包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    

    3.2 写一个类,里面写RestTemplate方法

    RestTemplate简介: pring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

    package cn.itsource.springcloud.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class BeanConfig {
    
        //交给Bean管理
        //@LoadBalanced :让RestTemplate 有负载均衡的能力
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    3.3主配置类

    package cn.itsource.springcloud;
    
    import cn.itsource.springcloud.config.BeanConfig;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
    import org.springframework.context.annotation.Import;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    @Import(BeanConfig.class)
    public class OrderApplication {
       
        public static void main(String[] args) {
            new SpringApplicationBuilder(OrderApplication.class).web(true).run(args);
        }
    
    }
    

    3.4 Controller层方法

    @GetMapping("/order/user/{id}")
        public User getUserById(@PathVariable("id") Long id){
            //String url = "http://localhost:2000/user/"+id;
            String url = "http://user-server/user/"+id;
            User user = restTemplate.getForObject(url, User.class);
            return user;
        }
    

    3.5 application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/
      instance:
        instance-id: first-one
        prefer-ip-address: true
    
    server:
      port: 2000
    
    spring:
      application:
        name: order
    

    4.Feign

    简介:Feign是基于Ribbon,同样具有负载均衡的能力

    4.1引入Feign的jar包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    4.2 配置类打上标签 @EnableFeignClients(“cn.itsource.springcloud.feignclient”) feignclient是接口类的包名

    package cn.itsource.springcloud;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableFeignClients("cn.itsource.springcloud.feignclient")
    public class OrderApplication {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(OrderApplication.class).web(true).run(args);
        }
    }
    

    4.3 写一个接口类

    package cn.itsource.springcloud.feignclient;
    
    import cn.itsource.springcloud.domain.User;
    import cn.itsource.springcloud.fallback.UserFeignClientFallback;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    //该客户端接口用来调用用户服务(user-server)
    // http://user-server/userserver/user/11  -> ribbon
    @FeignClient(value = "customer",fallback = UserFeignClientFallback.class)
    public interface UserFeignClient {
    
        //调用根据id获取用户的接口
        @GetMapping("/userserver/user/{id}")
        User getUserById(@PathVariable("id") Long id);
    }
    

    4.4 再写一个实现类

    package cn.itsource.springcloud.fallback;
    
    import cn.itsource.springcloud.domain.User;
    import cn.itsource.springcloud.feignclient.UserFeignClient;
    import org.springframework.stereotype.Component;
    
    @Component
    public class UserFeignClientFallback implements UserFeignClient {
    
        @Override
        public User getUserById(Long id) {
            //返回托底数据
            return new User(-1L,"null","用户服务获取失败");
        }
    }
    

    4.5 Controller控制层调用接口类

    package cn.itsource.springcloud.web.controller;
    
    import cn.itsource.springcloud.domain.User;
    import cn.itsource.springcloud.feignclient.UserFeignClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    //订单服务,消费者
    @RestController
    @RequestMapping("/orderserver")
    public class OrderServerController {
    
        @Autowired
        private UserFeignClient userFeignClient ;
    
        //浏览器调用,根据id获取用户 : 有负载均衡
        @GetMapping("/user/{id}")
        public User getUserById(@PathVariable("id")Long id){
            return userFeignClient.getUserById(id);
        }
    }
    

    4.6 application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/
      instance:
        instance-id: order-second
        prefer-ip-address: true
    
    server:
      port: 2001
    
    spring:
      application:
        name: order-second
    

    5.Hystrix

    5.1 导包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    

    5.2 配置类打上注解标签(开启Hystrix)

    @EnableCircuitBreaker
    

    5.3 Controller控制层 (需在公共类上写一个AjaxResult)

    package cn.itsource.springcloud.web.controller;
    
    
    import cn.itsource.springcloud.domain.User;
    import cn.itsource.springcloud.utils.AjaxResult;
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/orderserver")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        //这是订单服务,调用用户服务
        @HystrixCommand(fallbackMethod = "getUserByIdFallback")
        @GetMapping("/user/{id}")
        public AjaxResult getUserById(@PathVariable("id")Long id){
            String url = "http://customer/userserver/user/"+id;
            //customer是yml配置中application.name名
            //userserver是控制层的mapping
            User user = restTemplate.getForObject(url, User.class);
    
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.getData(user);
            return ajaxResult;
        }
    
        //编写降级方法
        public AjaxResult getUserByIdFallback(@PathVariable("id")Long id){
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.setSuccess(false);
            ajaxResult.setErroMessage("抱歉,订单服务不可能");
            return ajaxResult;
        }
    }
    

    5.4 application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/
      instance:
        instance-id: first-one
        prefer-ip-address: true
    
    server:
      port: 2000
    
    spring:
      application:
        name: order
    

    6.Zuul网关

    6.1 导入jar包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    

    6.2 主配置类上打注解标签 @EnableZuulProxy//开启zuul网关

    package cn.itsource.springcloud;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    import org.springframework.web.bind.annotation.RestController;
    
    @EnableZuulProxy//开启zuul网关
    @SpringBootApplication
    @RestController
    public class ZuulApplication {
    
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
        }
    }
    

    6.3 application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/
      instance:
        instance-id: first-one
        prefer-ip-address: true
    
    server:
      port: 4000
    
    spring:
      application:
        name: zuul-server
    
    zuul:
      routes:
        order: "/order/**" #别名---order是订单服务yml中application.name的名字
      prefix: "/pre" #前缀
      
      #浏览器访问格式:http://localhost:4000/pre/order/orderserver/user/10
    

    6.4 写一个过滤器的类,继承ZuulFilter,实现登录检查

    package cn.itsource.springcloud.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import org.apache.commons.lang.StringUtils;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.HashMap;
    
    public class ZuulByFilter extends ZuulFilter{
    
        //过滤器的类型 PRE_TYPE
        @Override
        public String filterType() {
            return "pre";
        }
    
        //过滤器的顺序
        @Override
        public int filterOrder() {
            return 1;
        }
    
        @Override
        public boolean shouldFilter() {
    
            //获取请求上下文
            RequestContext currentContext = RequestContext.getCurrentContext();
            //获取请求对象
            HttpServletRequest request = currentContext.getRequest();
            //获取请求的地址
            String requestURI = request.getRequestURI();
            //如果包含了login,则返回false
            if (requestURI.toUpperCase().contains("LOGIN")){
                return false;
            }
            return true;
        }
    
        //执行run方法-----中心方法
        @Override
        public Object run() throws ZuulException {
    
            //获取上下文对象
            RequestContext currentContext = RequestContext.getCurrentContext();
            //获取对象
            HttpServletRequest request = currentContext.getRequest();
            //获取相应对象
            HttpServletResponse response = currentContext.getResponse();
    
            //获取响应的数据格式
            response.setContentType("application/json;charset:utf-8");
            //获取请求头x-token
            String token = response.getHeader("x-token");
            //如果不存在请求头,则让重新登录
            if (StringUtils.isBlank(token)){
                HashMap<String,String> map = new HashMap<>();
                map.put("success", "false");
                map.put("errorMessage","麻烦请登录" );
                currentContext.setSendZuulResponse(false);
            }
            return null;
        }
    }
    

    7.Config

    7.1 导入jar包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    

    7.2 主配置类打上注解标签

    package cn.itsource.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    //@EnableDiscoveryClient
    //@EnableConfigServer :开启配置中心
    @SpringBootApplication
    @EnableConfigServer
    public class ConfigServerApplication5000 {
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication5000.class);
        }
    }
    

    7.3 application.yml (放在码云仓库中)

    server:
      port: 5000
    spring:
      application:
        name: config-server
        
      #码云仓库地址
      cloud:
        config:
          server:
            git:
              uri: https://gitee.com/xxxxx/zuul-server.git  #码云仓库
              username: xxxxx
              password: xxxxx
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/
      instance:
        prefer-ip-address: true #使用ip注册到注册中心
        instance-id: config-server:5000 #指定服务的id
    

    7.4 浏览器访问地址: localhost:5000/application-config-dev.yml

    实际要看码云中仓库名

    展开全文
  • 这是一个简单的SpringCloud整合五大组件注册中心Eureka、负载均衡Ribbon、熔断器Hystrix、伪装Feign、服务网关Zuu,旨在认识这五大组件,以及这五大组件该如何使用
  • springcloud五大组件

    2021-11-02 16:02:55
    简介:Spring Cloud Eureka是Spring Cloud Netflix项目下的服务治理模块。 由两个组件组成:Eureka服务端和Eureka客户端。 Eureka服务端用作服务注册中心。支持集群部署。 Eureka客户端是一个java客户端,用来...

    1、Eureka

    作用:实现服务治理(服务注册与发现)

    简介:Spring Cloud Eureka是Spring Cloud Netflix项目下的服务治理模块。

    由两个组件组成:Eureka服务端和Eureka客户端。

    Eureka服务端用作服务注册中心。支持集群部署。

    Eureka客户端是一个java客户端,用来处理服务注册与发现。

    在应用启动时,Eureka客户端向服务端注册自己的服务信息,同时将服务端的服务信息缓存到本地。客户端会和服务端周期性的进行心跳交互,以更新服务租约和服务信息。

    2、Ribbon

    作用:Ribbon,主要提供客户侧的软件负载均衡算法。

    简介:Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

    注意看上图,关键点就是将外界的rest调用,根据负载均衡策略转换为微服务调用。Ribbon有比较多的负载均衡策略,以后专门讲解。

    3、Hystrix

    作用:断路器,保护系统,控制故障范围。

    简介:为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。

    4、Zuul

    作用:api网关,路由,负载均衡等多种作用

    简介:类似nginx,反向代理的功能,不过netflix自己增加了一些配合其他组件的特性。

    在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。

    5、Config

    作用:配置管理

    简介:SpringCloud Config提供服务器端和客户端。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。

    这个还是静态的,得配合Spring Cloud Bus实现动态的配置更新。

    展开全文
  • 1. SpringCloud五大组件: 1.注册中心:Eureka,Nacos,Consul; 官方推荐使用的是Eureka,但是常用的是阿里提供的Nacos,而Consul基本很少使用 注册中心的作用: 避免服务与服务之间的调用(服务之间的调用是远程的...

    SpringCloud五大组件:

    1.注册中心:Eureka,Nacos,Consul;

    官方推荐使用的是Eureka,但是常用的是阿里提供的Nacos,而Consul基本很少使用
    注册中心的作用:
    避免服务与服务之间的调用(服务之间的调用是远程的)时把互相的地址/ip写死。一旦写死,如果有一方服务的地址发生改变,那么调用它的那一方就得修改地址,耦合性太高。
    所以这时候就需要使用注册中心来作为一个中间件,服务的提供者负责将自己的ip发送给注册中心,而服务的消费者只需要从注册中心拉取对应提供服务的地址/ip,这样服务的消费者就可以动态获取提供者的地址进行调用了。很好的实现了解耦。

    这里就讲一下Nacos的配置,因为Nacos是常用的,而且配置方法都相差不多

    Nacos的配置:

    1. 首先官网下载Nacos:Nacos1.1.3的版本下载地址
      1.1 下载完成解压后,进入bin目录,在终端中输入:sh startup.sh -m standalone 指令开启
    2. 创建一个Maven工程,然后创建一个服务的提供者模块,和一个服务的消费者模块
      在这里插入图片描述
    3. 在两个模块中的pom文件中导入依赖:
        <dependencies>
            <!--nacos-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                <version>0.2.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
                <version>1.1.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
        </dependencies>
    
    1. 在provider(服务的提供者)模块中创建配置文件:application.yml,并配置参数
    server:
      port: 8000
    spring:
      cloud:
        nacos:
          discovery:
            server-addr:  127.0.0.1:8848 # 配置nacos 服务端地址
      application:
        name: nacos-provider # 服务名称,大小写不敏感,一般与模块名一致(唯一的)
    

    这样就将该服务注册到了Nacos注册中心中
    consumer模块也是一样的配置 将server.port端口和application.name属性改一改就可以了

    1. 调用方法演示
    package com.itheima.nacos.controller;
    
    
    import com.itheima.nacos.domain.Goods;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    /**
     * 服务的调用方
     */
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    	/*
    		这个模板类可以自己创建一个包,在包下创建一个spring的配置类,加上@Configuration声明
    		在写一个方法,在方法上加上@Bean,返回值就是RestTemplate,方法体直接new RestTemplate()就可以了
    	*/
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
            //演示discoveryClient 使用
            List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
    
            //判断集合是否有数据
            if(instances == null || instances.size() == 0){
                //集合没有数据
                return null;
            }
    
            ServiceInstance instance = instances.get(0);
            String host = instance.getHost();//获取ip
            int port = instance.getPort();//获取端口
    
            System.out.println(host);
            System.out.println(port);
    
            String url = "http://"+host+":"+port+"/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
    
            return goods;
        }
    }
    
    
    1. 创建启动类,启动即可
      注意事项:Eureka如果想配置注册中心需要单独创建一个模块作为配置中心,不像Nacos和Consul是一个服务,直接下载启动就可以

    2.客服端负载均衡:Ribbon

    为什么要使用负载均衡策略?
    答:服务的提供方可能不仅仅只有一台服务器,而是一个集群,比如上面调用服务时,使用的是instances.get(0);这样就将调用的服务写死了,拿到的永远都是第一个服务,没有实现服务的均衡。
    Ribbon可以简化restTemplate的调用
    使用:
    在创建restTemplate方法时的@Bean上加上@LoadBalanced注解
    这样在contorller中代码就可以这样编写了:
    
    package com.itheima.nacos.controller;
    
    
    import com.itheima.nacos.domain.Goods;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    /**
     * 服务的调用方
     */
    
    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
        @GetMapping("/goods/{id}")
        public Goods findGoodsById(@PathVariable("id") int id){
    
            String url = "http://nacos-provider/goods/findOne/"+id;
            // 3. 调用方法
            Goods goods = restTemplate.getForObject(url, Goods.class);
    
    
            return goods;
        }
    }
    
    

    这样就实现了客户端的一个负载均衡
    Ribbon负责均衡策略:
    随机: RandomRule
    轮询 : RoundRobinRule (默认)
    最小并发: BestAvailableRule
    过滤: AvailabilityFilteringRule
    响应时间: WeightedResponse TimeRule
    轮询重试: RetryRule
    性能可用性: ZoneAvoidanceRule
    Ribbon还不是最终解决方案,因为路径写死了String url = “http://nacos-provider/goods/findOne/”+id;
    而且每启动一个服务都需要配置该路径,比较麻烦,所以就需要Feign组件完善

    3.声明式服务调用:Feign

    Feign概述:是一个声明式的 REST 客户端,它用了基于接口的注解方式,很方便实现客户端配置。之前在netfilx公司时是不支持SpringMvc注解的,后来别SpringCloud整合后支持了SpringMvc的注解
    

    使用步凑:

    1. 导入依赖
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
    

    2.编写Feign调用接口,接口编写规则:消费方调用提供方时,接口的编写尽量与消费方暴露的方法(也就是controller中的方法)一直

    package com.itheima.consumer.feign;
    
    
    import com.itheima.consumer.config.FeignLogConfig;
    import com.itheima.consumer.domain.Goods;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     *
     * feign声明式接口。发起远程调用的。
     *
     String url = "http://nacos-provider/goods/findOne/"+id;
     Goods goods = restTemplate.getForObject(url, Goods.class);
     *
     * 1. 定义接口
     * 2. 接口上添加注解 @FeignClient,设置value属性为 服务提供者的 应用名称
     * 3. 编写调用接口,接口的声明规则 和 提供方接口保持一致。
     * 4. 注入该接口对象,调用接口方法完成远程调用
     */
    @FeignClient(value = "nacos-provider")
    public interface GoodsFeignClient {
        @GetMapping("/goods/findOne/{id}")
        public Goods findGoodsById(@PathVariable("id") int id);
    }
    

    3.消费方的controller中直接注入该接口并调用方法即可
    注意:接口一般是不能注入使用的,但是spring会自动产生接口的代理对象,所以可以直接使用

    Feign的超时:两种
    1.连接超时 (服务调用服务的时间,默认时间1s)
    2.业务逻辑处理超时 (被调用方处理业务的时间,默认时间1s)
    可以自己配置,在yml配置文件中

    # 设置Ribbon的超时时间
    ribbon:
      ConnectTimeout: 1000 # 连接超时时间 默认1s  默认单位毫秒
      ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s 默认单位毫秒
    

    Feign的日志记录
    Feign 只能记录 debug 级别的日志信息。也是在yml配置文件中可以配置

    # 设置当前的日志级别 debug,feign只支持记录debug级别的日志
    logging:
      level:
        com.itheima: debug
    

    定义Feign日志级别Bean
    FeignLogConfig

    package com.itheima.consumer.config;
    import feign.Logger;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FeignLogConfig {
        /*
            NONE,不记录
            BASIC,记录基本的请求行,响应状态码数据
            HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
            FULL;记录完成的请求 响应数据
         */
        @Bean
        public Logger.Level level(){
            return Logger.Level.FULL;
        }
    }
    
    
    

    最后在声明的接口中的@FeignClient注解中加上configuration = FeignLogConfig.class属性即可

    4.熔断器:Hystrix

    Hystrix也是Netflix公司的
    用于隔离访问远程服务、第三方服务时出现级联失败(雪崩)
    也就是用户访问服务时,而这个服务也需要访问其它的服务,如果最底层的服务挂了,从而导致整条链路的服务都挂了,这就称为雪崩
    

    解决方案:
    隔离:
    1.线程池隔离(默认)
    例如:服务的调用方有一个线程池大小为100,这个服务需要调用其它的四个服务。这个时候,就会对100的线程池进行拆分,给每一个需要调用的服务配置一个单独的线程池,比如都是25的线程容量,如果其中的一个服务挂了,请求一直发一直发,直到25的线程容量用完后就不会在调用了,这样也不会影响其它服务的使用
    2.线程量隔离
    给服务的提供方设置一个阈值,也就是每次请求该服务的线程最大数是多少,如果超过了这个阈值,请求将不会在发送,也有效的隔离了服务之间的耦合
    降级:异常,超时
    服务的提供方和消费方都可以配置,也就是说在出现异常或则超时错误时采用自定义解决方案
    熔断
    用于监控微服务之间的调用情况
    该机制默认是关闭状态
    当请求的失败率达到一个阈值时(5秒失败20次),就会打开熔断器,打开后的一段时间内(默认5秒)所有的请求都将拒绝,直 到过了这段时间,会呈现一个半开状态,这时会放一些少量请求进来,如果请求失败,回到打开状态;如果成功,就回到关闭状态
    限流
    具体实现自己另外搜
    熔断的监控(可视化工具)
    Hystrix 提供了 Hystrix-dashboard 功能,用于实时监控微服务运行状态。
    但是Hystrix-dashboard只能监控一个微服务。
    Netflix 还提供了 Turbine ,进行聚合监控。
    Turbine搭建流程:添加链接描述
    5.网关:Gateway(需要单独起一个模块)
    概述:
    网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
    即:用于管理客服端发起请求时的路径,一个请求可能会调用多个微服务,如果每个微服务都需要客户端去调用,那么增加了客服端的压力;所以在这时候就需要一个Gateway组件,用于管理客服端的请求,由Gateway统一接收客户端的请求,在由Gateway去调用微服务。
    在这里插入图片描述
    网关模块yml配置如下:

    server:
      port: 80
    
    spring:
      application:
        name: api-gateway-server
    
      cloud:
        # 网关配置
        gateway:
          # 路由配置:转发规则
          routes: #集合。
          # id: 唯一标识。默认是一个UUID
          # uri: 转发路径
          # predicates: 条件,用于请求网关路径的匹配规则
          # filters:配置局部过滤器的
          - id: gateway-provider
            # 静态路由
            uri: http://localhost:8001/
            predicates:
            - Path=/goods/**
    

    该配置是有问题的,直接写死了微服务的地址,如果微服务的地址发生了改变,或者是个集群,那么这边也需要修改,耦合性太高
    解决:网关与微服务之间使用注册中心交互
    修改yml文件:

    server:
      port: 80
    
    spring:
      application:
        name: api-gateway-server
    
      cloud:
        # 网关配置
        gateway:
          # 路由配置:转发规则
          routes: #集合。
          # id: 唯一标识。默认是一个UUID
          # uri: 转发路径
          # predicates: 条件,用于请求网关路径的匹配规则
          # filters:配置局部过滤器的
    
          - id: gateway-provider
          	# 静态路由
            # uri: http://localhost:8001/
            # 动态路由
            uri: lb://GATEWAY-PROVIDER
            predicates:
            - Path=/goods/**
    

    5.Gateway过滤器:

    局部过滤器:
    也就是过滤单独的一个微服务;在yml配置文件中配置:

    server:
      port: 80
    spring:
      application:
        name: api-gateway-server
      cloud:
        # 网关配置
        gateway:
          # 路由配置:转发规则
          routes: #集合。
          # id: 唯一标识。默认是一个UUID
          # uri: 转发路径
          # predicates: 条件,用于请求网关路径的匹配规则
          # filters:配置局部过滤器的
    
          - id: gateway-provider
            # 静态路由
            # uri: http://localhost:8001/
            # 动态路由
            uri: lb://GATEWAY-PROVIDER
            predicates:
            - Path=/goods/**
            # 配置局部过滤器
            filters:
            - AddRequestParameter=username,zhangsan
    

    全局过滤器
    过滤所有的微服务
    1、 在Gateway模块中定义一个类实现GlobalFilter,Ordered接口
    2、在重写filter和getOrder方法
    代码:

    package com.itheima.gateway.filter;
    
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component
    public class MyFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
            System.out.println("自定义全局过滤器执行了~~~");
    
            return chain.filter(exchange);//放行
        }
    
        /**
         * 过滤器排序
         * @return 数值越小 越先执行
         */
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    
    
    展开全文
  • SpringCloud五大组件详细分析&配置

    千次阅读 2020-08-05 12:53:13
    SpringCloud五大组件详细分析&配置1.服务发现——Netflix Eureka1.1.什么是Eureka1.2.Eureka和Zookeeper...

    最近项目需要使用SpringCloud,对于SpringCloud的五大服务做了一个整理,并进行了一定的调研,现将整理的内容记录如下。本文所探讨的是是什么,以及怎么用的问题,如果想研究底层实现的同学可以绕道。
    首先,介绍一下SpringCloud:
    长久以来,开发人员在繁杂的开发过程中,需要做很多基础的配置,同时在引用其他组件时,需要花费大量的时间去研究组件调用方法。导致大量的时间被浪费。
    也正在此时,spring横空出世,并经历了spring ->>spring boot ->>SpringCloud的发展。SpringCloud对很多流行的子项目进行了封装,同时提出了约定大于配置的思想。使开发人员逃离了大量繁重的配置任务,进而去更多的关注业务实现。
    Spring Cloud由众多子项目组成,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Consul 等,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。其中,主要的五大组件如下:
    服务发现——Netflix Eureka
    客服端负载均衡——Netflix Ribbon
    断路器——Netflix Hystrix
    服务网关——Netflix Zuul
    分布式配置——Spring Cloud Config

    1.服务发现——Netflix Eureka

    1.1.什么是Eureka

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。功能类似于Dubbo的注册中心Zookeeper。具体的实现逻辑如下图所示:
    在这里插入图片描述
    Eureka包含两个组件:Eureka Server和Eureka Client。
    Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
    Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
    在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
    Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

    1.2.Eureka和Zookeeper的差别

    现有市场上主流的服务注册实现方案,主要包括两大类:Eureka和Zookeeper。
    著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。

    1.2.1.Zookeeper保证CP

    当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

    1.2.2.Eureka保证AP

    Eureka看明白了这一点,因此在设计时就优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或时如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

    1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
    2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
    3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
      因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

    1.3.使用idea搭建eureka注册中心

    1.3.1使用Spring Initializr搭建

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    1.3.2修改配置文件和启动类

    在这里插入图片描述
    配置文件修改为以下内容:

    server:
      port: 8081
    # 服务名称:在服务发现中,服务名称是一个关键信息,如果同一个服务名称有多个实例,那么,消费者在调用的时候就可以使用ribbon提供的负载均衡来调用
    spring:
      application:
        name: server-register
    eureka:
      instance:
        #显示IP地址
        prefer-ip-address: true
        #默认值为:机器名称:服务名称:实例得端口,一般需要机器名称,按照以下模式修改即可
        instance-id: ${spring.application.name}:${server.port}
        hostname: localhost
      client:
        service-url:
          #注册中心的地址
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
        #单机版可以使用以下配置
        #是否把自己注册到eureka上
        register-with-eureka: false
        #是否从eureka上拉取服务列表
        fetch-registry: false
    
       

    启动类添加@EnableEurekaServer注解,如下图所示:
    在这里插入图片描述
    启动后页面展示:
    在这里插入图片描述

    1.4使用idea搭建eureka Client端

    1.4.1搭建框架

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    如果需要web功能,可以添加web包引用,如上图所示
    在这里插入图片描述

    1.4.2修改配置文件

    在这里插入图片描述
    内容如下:

    server:
      port: 8090
    spring:
      application:
        name: client-1
    eureka:
      instance:
        #显示IP地址
        prefer-ip-address: true
        #默认值为:机器名称:服务名称:实例得端口
        instance-id: ${spring.application.name}:${server.port}
      client:
        serviceUrl:
          defaultZone: http://localhost:8081/eureka/
    
    • client端不需要在启动类上添加@EnableEurekaServer注解即可启动
      启动后可以在eureka中查看到该client端,如下所示:
      在这里插入图片描述

                                      </div><div data-report-view="{&quot;mod&quot;:&quot;1585297308_001&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/fzp12345/article/details/103685261&quot;,&quot;extend1&quot;:&quot;pc&quot;,&quot;ab&quot;:&quot;new&quot;}"><div></div></div>
                  <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
                                  </div>
      
    展开全文
  • SpringCloud五大组件(一看就会) 前言   Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、...
  • SpringCloud五大组件Hystrix 分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,...
  • springcloud五大组件是哪些 springcloud五大组件: 1、Eureka 作用:实现服务治理(服务注册与发现) 简介:Spring Cloud Eureka是Spring Cloud Netflix项目下的服务治理模块。 由两个组件组成:Eureka服务端和...
  • SpringCloud五大组件详细分析以及配置

    千次阅读 2019-12-24 16:31:47
    SpringClound五大组件详细分析以及配置欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定...
  • spring cloud组件实例

    2019-01-16 23:22:54
    spring cloud组件实例代码,可以直接运行,适合学习spring cloud
  • SpringCloud五大组件Zuul

    2020-07-28 15:10:27
    SpringCloud五大组件Zuul 介绍: Zuul是Netflix开源的微服务网关,可以和Eureka、Ribbon、Hystrix等组件配合使用,Spring Cloud对Zuul进行了整合与增强,Zuul默认使用的HTTP客户端是Apache HTTPClient,也可以使用...
  • SpringCloud五大组件(一)粗解

    千次阅读 2020-07-01 18:40:38
    SpringCloud提供一个工具“Feign”为我们省略了这个过程,每次只需要直接开车去找B和C,而不是每次都先要造车子。 @FeignClient("B或者C的服务名") public class A_Find_B_C{ @RequestMapping(value = "/test/{B_id...
  • Spring Cloud 五大组件及其功能

    千次阅读 2020-05-14 17:05:54
    一、spring cloud ...二、五大常用组件 服务发现——Netflix Eureka 客服端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关——Netflix Zuul 分布式配置——Spring Cloud Config ...
  • 1. Eureka原理 Eureka作为微服务中的注册中心,其服务注册于发现的原理如下: 首先有两个角色,一个服务端和客户端,服务端就是Eureka本身,客户端就是服务提供者和消费者,当服务提供者启动... 但是由于服务之间的调
  • springcloud五大组件1:什么是eureka?2:什么是ribbon?3:什么是hystrix?4:什么是feign?5:什么是zuul? 1:什么是eureka? eureka是服务的注册中心 ,它的作用是为我们微服务提供服务的注册与发现,Eureka...
  • 发现——Netflix Eureka a.微服务调用过程 ... 说到分布式系统这里不得不提一下“CAP原则“:CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition ...
  • Springcloud五大组件

    2021-07-21 14:33:59
    https://m.php.cn/faq/466292.html springcloud五大组件:1、Eureka实现服务治理;2、Ribbon主要提供客户侧的软件负载均衡算法;3、Hystrix断路器,保护系统,控制故障范围;4、Zuul,api网关,路由,负载均衡等多种...
  • Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。...
  • 4.1 快速入门 1) 导入依赖 <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-openfeignartifactId> dependency> 2) 开启Feign功能 我们在启动类上,添加注解@...
  • 什么是Feign? Feign是一个声明式的Web服务客户端,使得编写Web服务客户端变得非常容易, 只需要创建一个接口,然后在上面添加...Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConvert..
  • Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端...
  • 完整的spring cloud体系,全部的Spring cloud组件,深入理解,浅显易懂,让你也能搭起来微服务的架构!!!!!!!
  • SpringCloud五大组件Config SpringCloudConfig配置中心我们使用Bus来做刷新配置 简介: Spring Cloud Config 是 Spring Cloud 家族中最早的配置中心,虽然后来又发布了 Consul 可以代替配置中心功能,但是 Config ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,375
精华内容 6,150
关键字:

springcloud五大组件

spring 订阅