springcloud学习基础

  • 什么是分布式
  1. 不同模块部署在不同服务器上  作用:  分布式解决网站高并发带来问题
  • 什么是SOA 
  1. SOA:Service Oriented Architecture面向服务的架构。也就是把工程拆分成服务层、表现层两个工程。服务层中包含业务逻辑,只需要对外提供服务即可。表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。

  • 什么是集群
  1. 多台服务器部署相同应用构成一个集群   作用: 通过负载均衡设备共同对外提供服务
  • 什么是RPC
  1. RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。
    RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。

  2. rpc远程调用框架:
    a.  RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol) 和java的原生序列化
    b.  Hessian,是一个轻量级的remoting onhttp工具,使用简单的方法提供RMI功能。 基于HTTP协议,采用二进制编解码。 
    c.  thrift是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。
    d.  SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。
  • SOA架构与微服务架构
  1.  SOA架构--面向服务架构
    业务系统分解为多个组件,让每个组件都独立提供离散,自治,可复用的服务能力
    通过服务的组合和编排来实现上层的业务流程,如将如业务逻辑层、数据访问层做成一个项目,controller层做成一个项目
    作用:简化维护,降低整体风险,伸缩灵活  
     
    SOA架构主要针对企业级、采用ESB服务(ESB企业服务总线),非常重,需要序列化和反序列化,采用XML格式传输。ESB也可以说是传统中间件技术与XML、Web服务等技术相互结合的产物。 
  2. 微服务架构 
     微服务架是从SOA架构演变过来,比SOA架构粒度会更加精细每个服务必须独立部署,互不影响,独立运行,基于Http+Rest+JSON格式传输。更加体现轻量级、小巧,
  • restful、soap、rpc
  1. RESTful是一种架构设计风格,提供了设计原则和约束条件,而不是架构。而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务。
  2. SOAP,简单对象访问协议是一种数据交换协议规范,
    是一种轻量的、简单的、基于XML的协议的规范。SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的。
    SOAP的消息是基于xml并封装成了符合http协议,因此,它符合任何路由器、 防火墙或代理服务器的要求。
    soap可以使用任何语言来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台无需修改即可正常使用。
  3. RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
    RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
    RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
    RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
  • 什么事springcloud
  1. SpringCloud 是一个RPC微服务框架,为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。 
     
      

    SpringCloud config 分布式配置中心
    SpringCloud netflix 核心组件
    Eureka:服务治理  注册中心
    Hystrix:服务保护框架
    Ribbon:客户端负载均衡器
    Feign:基于ribbon和hystrix的声明式服务调用组件
    Zuul: 网关组件,提供智能路由、访问过滤等功能。
  • 搭建服务注册eureka
  1. eureka是一个服务注册和发现模块。 
    在服务注册与发现中,有一个注册中心,当服务器启动时,会把当前服务器的信息以别名方式注册到注册中心上。
    另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,再实现rpc调用。 
     
  2. 创建springboot项目,在pom.xml中引入依赖
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.basic</groupId>
      <artifactId>eureka-server</artifactId>
      <version>1.0-SNAPSHOT</version>
      <name>eureka-server</name>
      <url>http://www.example.com</url>
      
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
      </parent>
      <!-- 管理依赖 -->
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.RC2</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
      <dependencies>
        <!--SpringCloud eureka-server -->
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
      </dependencies>
      <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
      <repositories>
        <repository>
          <id>spring-milestones</id>
          <name>Spring Milestones</name>
          <url>https://repo.spring.io/libs-milestone</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
    
    
    </project>
    

     

  3. 在application.yml配置
    ###服务端口号
    server:
      port: 8761
    ###eureka 基本信息配置
    eureka:
      instance:
        ###注册到eurekaip地址
        hostname: 127.0.0.1
      client:
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
        ###因为自己是为注册中心,不需要自己注册自己,集群情况下需设置true
        register-with-eureka: false
        ###因为自己是为注册中心,不需要检索服务
        fetch-registry: false

     

  4. 创建启动类EurekaServerApplication .java
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    
    /**
     * Hello world!
     *
     */
    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaServer
    {
        public static void main( String[] args )
        {
            SpringApplication.run(EurekaServer.class, args);
        }
    }
    
  5. 测试地址:http://localhost:8761/

    http://localhost:8761 ,界面如下:

    No application available 没有服务被发现 ……^_^ 
    因为没有注册服务当然不可能有服务被发现了。

  • 服务提供者 eureka-client
  1. 创建一个服务提供者 (eureka client),当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。
    下例:将一个订单服务注册到注册中心去

  2. 创建一个eureka-client项目
  3. 在pom.xml中引入依赖, 和eureka-server一样
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.basic</groupId>
        <artifactId>eureka-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-client</name>
        <description>Demo project for Spring Boot</description>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
        
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RC2</spring-cloud.version>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <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>
            <!--springboot 2.X eureka 依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
    
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

     

  4. 在application.yml中配置
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/ #表示将该服务注册到 'http://localhost:8761/eureka/'地址的注册中心
    server:
      port: 8762
    spring:
      application:
        name: orderService  # 将该服务注册到注册中心使用的别名

     

  5. 创建EurekaClientApplication.java
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class EurekaClientApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaClientApplication.class, args);
        }
    
    }

     

  6. 创建订单的控制类 OrderController.java
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-09 22:16
     */
    @RestController
    public class OrderController {
    
        /**
         * 查询所有订单
         * @return
         */
        @GetMapping("/findAll")
        public List<String> index(){
            List<String> strList = new ArrayList<String>();
            strList.add("20190001");
            strList.add("20190002");
            strList.add("20190003");
            return strList;
        }
    }

     

  7. 启动  // 启动前记得先启动服务注册,否则会报错
  8. 测试地址:
    http://localhost:8761/
    http://localhost:8762/findAll
    演示效果

    需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name 。 
    启动工程,打开http://localhost:8761 ,即eureka server 的网址:

     

    你会发现一个服务已经注册在服务中了,服务名为ORDERSERVICE ,端口为8762

  • 服务消费端(rest+ribbon)
  1. 在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。底层使用的是http协议,服务之间调用时基于httpclient
  2. ribbon是一个负载均衡客户端,可以很好的控制htttcp的一些行为。Feign默认集成了ribbon
  3. 准备工作:
    启动eureka-server 工程;
    启动
    eureka-client工程,它的端口为8762;
    启动
    eureka-client2工程,它的端口为8763; //按照上面方式创建,可将OrderController.java的方法内容修改下。其余不变
    这样我们orderService注册了2个实例,下面我们就来用rest来实现服务的调用,ribbon来实现负载均衡。
  4. 创建一个eureka-rest-ribbon工程
  5. 在pom.xml中引入依赖
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.basic</groupId>
        <artifactId>eureka-rest-ribbon</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-rest-ribbon</name>
        <description>Demo project for Spring Boot</description>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RC2</spring-cloud.version>
        </properties>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <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>
            <!--springboot 2.X eureka 依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
            <!--  ribbon  -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </dependency>
    
    
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

     

  6. 在application.yml中配置
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/ 
    server:
      port: 8764
    spring:
      application:
        name: eureka-rest-ribbon  

     

  7. 创建一个TemplateService.java,来调用订单服务
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-10 21:07
     */
    @Service
    public class TemplateService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        //  orderService就是你需要调用服务在eureka的注册名
        public Object find(){
            return restTemplate.getForObject("http://orderService/findAll", List.class);
        }
    }

     

  8. 创建一个IndexController.java,来调用TemplateService

    import com.basic.service.TemplateService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * Create by wangxb
     * 2019-06-09 23:11
     */
    @RestController
    public class IndexController {
    
        @Autowired
        private TemplateService templateService;
    
        @GetMapping("rest")
        public Object find(){
            return templateService.find();
        }
    }
  9. 在启动类
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class EurekaRestRibbonApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaRestRibbonApplication.class, args);
        }
    
        @Bean   // 注入RestTemplate
        @LoadBalanced // 开启负载均衡
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    
    }

     

  10. 启动测试:http://localhost:8764/rest   演示结果:浏览器交替显示client、client1的findAll结果
  • 服务消费端(feign)
  1. 什么是Feign
    Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果
    Feign 采用的是基于接口的注解
    Feign 整合了ribbon
  2. 准备工作
    启动eureka-server端口8761工程
    启动orderService端口8762工程
    启动orderService端口8763工程
  3. 创建一个feign工程
  4. 在pom.xml中添加依赖
     <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>

     

  5. 在application.yml中配置
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8765
    spring:
      application:
        name: service-feign

     

  6. 创建FeignService.java
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-10 7:25
     */
    @FeignClient("orderService")  // orderService就是服务的提供者在eureka的注册名
    public interface FeignService {
    
        // findAll时orderService工程的controller路径
        @RequestMapping(value = "/findAll", method = RequestMethod.GET)
        List<String> findAll();
    
    }

     

  7. 创建IndexController.java
    import com.basic.feign.FeignService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * Create by wangxb
     * 2019-06-10 7:22
     */
    @RestController
    public class IndexController {
        @Autowired
        private FeignService feignService;
    
        @GetMapping("/feign")
        public Object index(){
            return feignService.findAll();
        }
    }

     

  8. 启动类
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    public class FeignApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(FeignApplication.class, args);
        }
    
    }

     

  9. 启动测试: http://localhost:8765/feign
  • Hystrix断路器
  1. 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+RibbonFeign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的雪崩”效应。API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞
  2. 什么是Hystrix

    Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:

    较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 520次) 断路器将会被打开。

    断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

  3. 准备工作
    启动eureka-server项目
    启动eureka-client项目
  4. 在eureka-rest-ribbon项目的pom.xml中添加依赖
    <!--  hystrix  -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>

     

  5. 在eureka-rest-ribbon项目的ReplateService.java调用订单服务的方法添加@HystrixCommand注解
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-10 21:07
     */
    @Service
    public class TemplateService {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @HystrixCommand(fallbackMethod = "error")  // 如果调用失败,则调用error方法, 默认开启的线程池隔离、隔离、熔断机制
        public Object find(){
            return restTemplate.getForObject("http://ORDERSERVICE/findAll", List.class);
        }
    
        public String error(){
            return "调用订单服务出错拉!!!";
        }
    }
  6. 启动类添加@EnableHystrix注解
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EnableEurekaClient
    @EnableHystrix
    public class EurekaRestRibbonApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaRestRibbonApplication.class, args);
        }
    
        @Bean   // 注入RestTemplate
        @LoadBalanced // 开启负载均衡
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
    
    }
  7. 测试
    测试地址: http://localhost:8764/rest  浏览器正常相应数据
    现在我们将eureka-client服务停止,再次访问http://localhost:8764/rest , 浏览器会返回我门定义的error方法内容
  • Feign使用断路由
  1. Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码: feign.hystrix.enabled=true
  2. 准备工作
    启动eureka-server工程
    启动eureka-client工程
  3. 在feign工程的application.yml中添加配置
    feign:
      hystrix:
        enabled: true #开启feign断路由
    ###设置调用的超时时间,默认是1秒,一般是10秒或5秒
    hystrix:
       command: 
         default: 
           execution: 
            isolation:
             thread: 
              timeoutInMilliseconds: 5000
    

     

  4. 创建FeignHystrixService.java类,  实现FeiginService.java接口
    import org.springframework.stereotype.Component;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-10 21:58
     */
    @Component
    public class FeignHystrixService implements FeignService {
    
        @Override
        public List<String> findAll() {
            System.out.println("feign:调用订单服务失败!!!");
            return null;
        }
    }

     

  5. 在FeignService.java添加错误回调fallback
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import java.util.List;
    
    /**
     * Create by wangxb
     * 2019-06-10 7:25
     */
    @FeignClient(value = "orderService-hi",fallback=FeignHystrixService.class)
    public interface FeignService {
    
        @RequestMapping(value = "/findAll", method = RequestMethod.GET)
        List<String> findAll();
    
    }

    也可以使用 @HystrixCommand注解

  6. 测试
    访问地址:http://localhost:8765/feign,浏览器正常返回数据。
    将eureka-client项目停止,在访问,观察控制台error信息。
  7. 另外如果网络延迟,也可以配置Feign客户端超时时间,默认1.5 

    ###设置feign客户端超时时间

    ribbon:

    ###指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。

     ReadTimeout: 5000

    ###指的是建立连接后从服务器读取到可用资源所用的时间。

     ConnectTimeout: 5000

  • 服务网关Zuul
  1. 什么是网关 
     Zuul的主要功能是路由转发和过滤器。拦截所有请求发,分发到服务上去,路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能, 类似于nginx转发。
  2. 创建zuul-service工程,在pom.xml中依赖
     
    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.basic</groupId>
      <artifactId>zuul</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <repositories>
        <repository>
          <id>spring-milestones</id>
          <name>Spring Milestones</name>
          <url>https://repo.spring.io/milestone</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RC2</spring-cloud.version>
      </properties>
    
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
      </parent>
    
      <dependencies>
        <!--springboot 2.X eureka 依赖 -->
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </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>
      </dependencies>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    
    </project>
    
  3. 在resources的application.yml的配置如下
     
    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8769
    spring:
      application:
        name: service-zuul
    zuul:
      routes:
        api-a:
          path: /api-order/**
          service-id: orderService  #表示访问zuul的地址/api-order/**,就会转发到在eureka注册的服务名位orderService的工程下,
                                    #如:http://127.0.0.1:8769/api-order/findAll,zuul就会转发到orderService工程下的@GetMapping("/findAll")的controller下
    #    api-b:
    #      path: /api-other/**   如果还有其他服务可以接着配置
    #      service-id: other
    

     
  4. 编写测试类 AppZuul.java
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    /**
     * Hello world!
     *
     */
    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy // 开启网关
    public class AppZuul
    {
        public static void main( String[] args )
        {
            SpringApplication.run(AppZuul.class, args);
        }
    }

     

  5. 启动AppZuul.java 
     测试地址http://127.0.0.1:8769/api-order/findAll
     
     
  6. 这里我们可以配置网关服务过滤拦截 
     
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import javax.servlet.http.HttpServletRequest;
    
    @Component
    public class MyFilter extends ZuulFilter {
    
        private static Logger log = LoggerFactory.getLogger(MyFilter.class);
    
        @Override
        public String filterType() {
            return "pre";
        }
    
        @Override
        public int filterOrder() {
            return 0;
        }
    
        public boolean shouldFilter() {
            return true;
        }
    
        public Object run() {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
            Object accessToken = request.getParameter("token");
            if (accessToken != null) {
                return null;  // 表示为null则放行
            }
            log.warn("token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().getWriter().write("token is empty");
            } catch (Exception e) {
            }
            return null;
    
        }
    }

     
  7. 重启启动AppZuul.java  
     测试1:如果请求参数中没有传token ,http://127.0.0.1:8769/api-order/findAll
     
     测试1:如果请求参数中有传token ,http://127.0.0.1:8769/api-order/findAll?token=123
     
     这里可以根据自己的业务场景,配置
  8. 图解如何实现网关的高可用 
     
     
     
  • 分布式配置中心
  1. 什么是配置中心 
     在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

  2. https://gitee.com注册账号,创建好项目,并完成如下操作  
     
     项目创建完成后,在你的项目中上传config-client-dev.properties配置文件, 内容如下  --dev环境
     
    userName=dev-admin
    将文件上传
     
      
      
     
     点击提交
     
     复制你的文件地址
     
  3.  config的服务工程
     
     创建config-server工程,在pom.xml中引入依赖
     
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.basic</groupId>
      <artifactId>config-server</artifactId>
      <version>1.0-SNAPSHOT</version>
      <repositories>
        <repository>
          <id>spring-milestones</id>
          <name>Spring Milestones</name>
          <url>https://repo.spring.io/milestone</url>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RC2</spring-cloud.version>
      </properties>
    
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
      </parent>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
        </dependency>
    
      </dependencies>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    
    </project>
    
    在 application.preperties配置如下
     
    spring.application.name=config-server
    server.port=8889
    spring.cloud.config.server.git.uri=https://gitee.com/lehuix/xiaobo.git
    spring.cloud.config.server.git.searchPaths=respo
    spring.cloud.config.label=master
    spring.cloud.config.server.git.username=
    spring.cloud.config.server.git.password=
    创建ConfigServer.java启动类
     
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    /**
     * Hello world!
     *
     */
    @SpringBootApplication
    @EnableConfigServer
    public class ConfigServer
    {
        public static void main( String[] args )
        {
            SpringApplication.run(ConfigServer.class, args);
        }
    }
    
    启动ConfigServer.java测试,访问地址:
      
     
     
     
  4. config的客户端工程
     创建confg-client工程,在pom.xml中引入依赖
     
     
     在resource的application.preperties配置如下
      
     
     创建启动类
      
     
     启动测试,访问地址
     
  5. 未成功
     
     

  6.  
     

  7.  
     

  8.  
     

  9.  
     
  10. f
  11. f
  12. f
  13. f
  14. f
  15. f
  16. f
  17. f
  18. f
  19. f
  20. f
  21. f
  22. f
  23. f
  24. f
  25. f
  26. f
  27. f
  28. f
  29. f
  30. f
  31. f
  32. d
  33. d
  34. d
  35. d
  36. d
  37. d
  38. d
  39. d
  40. d
  41. d
  42. d
  43. d
  44. d
  45. d
  46. d
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值