springcloud基础总结

SpringCloud

1. 概念

1.1 微服务的技术栈
  • 负载均衡,网关路由:高可用、集群部署,校验、请求转发、服务集成。
  • 服务治理:服务注册、发现。
  • 容错:避免雪崩。
  • 监控跟踪:监控资源利用、服务响应、容器资源利用情况。
  • 消息总线:消息队列、异步通信。
  • 配置管理:统一配置管理。
1.2 Spring Cloud是什么

​ Spring Cloud为开发人员构建微服务架构提供了完整的解决方案,SpringCloud是若干个框架的集合,它包括spring-cloud-config、spring-cloud-bus等近20个子项目,它提供了服务治理、服务网关、智能路由、负载均衡、断路器、监控跟踪、分布式消息队列、配置管理等领域的解决方案。

1.3 Spring Cloud技术栈

​ 微服务的兴起出现了很多优秀的公司和技术:

  • 服务治理:Dubbo(阿里巴巴)、Dubbox(当当)、Eureka(Netflix)等 。
  • 配置管理:Disconf(百度)、QConf(360)、Diamood(淘宝)等 。
  • 服务跟踪:Hydra(京东)、Zipkin(Twitter)、Sleuth(Spring Cloud)等 。
1.4 为什么使用Spring Cloud

​ 微服务架构的优点表明它可以提高我们的生产力,但是分布式系统本身的技术成本问题给互联网那些创业型公司不少的挑战,阿里、百度等巨头所提供的微服务技术只是解决其中某个问题,而整合封装这些优秀的技术恐怕是Spring最擅长的领域了,Spring Cloud也正因为此而诞生。
  使用Spring Cloud来构建微服务架构可以省去你整合各家技术的成本,Spring Cloud为我们构建微服务架构提供了一站式的解决方案,就好比当初Spring诞生是为解决EJB企业应用开发的众多问题而提供的一站式轻量级企业应用开发解决方案一样,随着使用Spring Cloud公司数量的增加,相信微服务将被Spring Cloud一统江湖。

1.5 服务治理
- 什么是服务治理:

- 微服务架构的缺点中最主要的就是由于微服务数量众多导致维护成本巨大,服务治理为解决此问题而产生的。服务治理的作用是让维护人员从人工维护中解放出来,由服务自维护,微服务作为服务提供方主动向服务治理中心注册,服务的消费方通过服务治理中心查询需要的服务并进行调用。

1.6 负载均衡
  • 负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等 ,软件比如:LVS、Nginx等 。

  • 用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。

1.7 容错保护
  • 容错保护是指微服务在执行过程中出现错误并从错误中恢复的能力。微服务容错性不好很容易导致雪崩效应,

  • 微服务的雪崩效应表现在服务与服务之间调用,当其中一个服务无法提供服务可能导致其它服务也死掉,比如:单点登录服务调用用户信息服务查询用户信息,由于用户信息服务无法提供服务导致单点登录服务一直等待,从而导致用户登录、用户退出功能无法使用,像这样由一个服务所引起的一连串的多个服务无法提供服务即是微服务的雪崩效应。

  • Spring Cloud Hystrix
      Spring Cloud Hystrix 是基于Netflix的开源框架Hystrix的整合,它实现了断路器、线程隔离、信号隔离等容错功能。

1.8 服务网关

服务网关是在微服务前边设置一道屏障,请求先到服务网关,网关会对请求进行过虑、校验、路由等处理。有了服务网关可以提高微服务的安全性,校验不通过的请求将被拒绝访问。
  前边介绍的Ribbon客户端负载均衡技术可以不用经过网关,因为通常使用Ribbon完成微服务与微服务之间的内部调用,而对那些对外提供服务的微服务,比如:用户登录、提交订单等,则必须经过网关来保证微服务的安全。

  • Spring Cloud Zuul
      Spring Cloud Zuul是整合Netflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过虑等 功能。

2. 创建注册中心Eureka

2.1 添加依赖
  • 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>org.example</groupId>
        <artifactId>springcloud-test-eureka</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <artifactId>spring-boot-starter-parent</artifactId>
            <groupId>org.springframework.boot</groupId>
            <version>1.5.2.RELEASE</version>
            <relativePath />
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
            </dependency>
            <!-- spring boot test -->
            <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>Dalston.RC1</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>
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    </project>
    
    
2.2 写配置文件
  • application.yml

    server:
      port: 8888
    eureka:
      instance:
        hostname: localhost
    
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url: 
          defaultZone: http://${eureka.instance.hostname}:${eureka.port}/eureka/
    
2.3 启动
  • 创建EurekaApp.java
package com.zsl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author m1767
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApp.class,args);
    }
}

2.4 结果演示

在这里插入图片描述

2.5 小笔记
  • 通过注册中心来实现各个服务的管理,方便服务的管理。

3. 创建会员服务

3.1 添加依赖
  • 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>org.example</groupId>
        <artifactId>springcloud-test-member</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <artifactId>spring-boot-starter-parent</artifactId>
            <groupId>org.springframework.boot</groupId>
            <version>1.5.2.RELEASE</version>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</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>Dalston.RC1</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>
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    </project>
    
3.2 配置文件
  • application.yml

    eureka:
      client:
        service-url:
          defaultZone: http://localhost:9999/eureka/
    
    
    server:
      port: 9763
    spring:
      application:
        name: member
    
    
3.3 创建MemberController与MemberService
  • MemberController

    package com.zsl.controller;
    
    import com.zsl.service.MemberService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author m1767
     */
    @RestController
    public class MemberController {
        @Value("${server.port}")
        private String port;
    
        @Autowired
        private MemberService memberService;
    
        @RequestMapping("/getUsers")
        public List<String> getMemberList(){
            return memberService.getMemberList();
        }
    
        @RequestMapping("/info")
        public String getInfo(){
            return "this is member service!";
        }
    }
    
    
  • MemberService

    package com.zsl.service;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author m1767
     */
    @Service
    public class MemberService {
    
        public List<String> getMemberList(){
            List<String> users = new ArrayList<String>();
            users.add("小包子");
            users.add("大头");
            return users;
        }
    }
    
    
3.4 启动
  • MemberApp

    package com.zsl;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    /**
     * @author m1767
     */
    @SpringBootApplication
    @EnableEurekaClient
    public class MemberApp {
        public static void main(String[] args) {
            SpringApplication.run(MemberApp.class,args);
        }
    }
    
    
3.5 演示结果
  • 在注册中心的结果显示。注册中心发现了member服务

  • 在这里插入图片描述

  • 访问 会员服务的/getUsers

  • 在这里插入图片描述

3.6 小笔记
  • 每一个服务都是Eureka客户端,与Eureka服务端连接,进而可以实现Eureka服务端上的服务相互连通

4. 创建订单服务

4.1 添加依赖
  • 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>org.example</groupId>
        <artifactId>springcloud-test-order</artifactId>
        <version>1.0-SNAPSHOT</version>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.2.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</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>Dalston.RC1</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>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    
    </project>
    
4.2 配置文件
  • application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:9999/eureka/
    
    server:
      port: 9764
    
    spring:
      application:
        name: order
    
4.3 创建OrderController和OrderService
  • OrderController

    package com.zsl.controller;
    
    import com.zsl.service.OderService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    /**
     * @author m1767
     */
    @RestController
    public class OrderController {
    
        @Autowired
        private OderService oderService;
    
        @RequestMapping("/getOrderUsers")
        private List<String> getOrderAll(){
            System.out.println("订单服务开始调用会员服务");
            return oderService.getOderByUsers();
        }
    
        @RequestMapping("/info")
        public String getInfo(){
            return "this is order service!";
        }
    }
    
    
  • OrderService

    package com.zsl.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    /**
     * @author m1767
     */
    @SuppressWarnings("unchecked")
    @Service
    public class OderService {
    
        @Autowired
        RestTemplate restTemplate;
    
        public List<String> getOderByUsers(){
            return restTemplate.getForObject("http://member:9762/getUsers",List.class);
    
        }
    }
    
    
4.4 启动
  • OrderApp

    package com.zsl;
    
    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;
    
    /**
     * @author m1767
     */
    @EnableEurekaClient
    @SpringBootApplication
    public class OrderApp {
        public static void main(String[] args) {
            SpringApplication.run(OrderApp.class,args);
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
    
4.5 演示结果
  • Eureka注册中心

  • 在这里插入图片描述

  • 访问服务

  • 在这里插入图片描述

4.6 小笔记
  • 一个服务调用另外一个服务可以通过另一个服务的服务名进行访问。

5. 网关配置

5.1 添加依赖
  • 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>org.example</groupId>
        <artifactId>springcloud-test-zuul</artifactId>
        <version>1.0-SNAPSHOT</version>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.2.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-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>Dalston.RC1</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>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    
        
    </project>
    
5.2 配置文件
  • application.yml

    eureka:
      client:
        service-url:
          defaultZone: http://localhost:9999/eureka/
    
    server:
      port: 9966
    
    spring:
      application:
        name: network
    
    zuul:
      host:
        connect-timeout-millis: 60000
        socket-timeout-millis: 60000
      routes:
        api-a:
          path: /api-member/**
          service-id: member
        api-b:
          # 自定义路径
          path: /api-order/**
          # 服务id
          service-id: rder
    
    
5.3 创建过滤器
package com.zsl.filter;

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;

/**
 * @author m1767
 */
@Component
public class TokenFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(TokenFilter.class);

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    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;
        }
        log.warn("token is empty");
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(401);
        try {
            ctx.getResponse().getWriter().write("token is empty");
        } catch (Exception e) {
        }
        return null;
    }
}

5.4 启动
package com.zsl;

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;

/**
 * @author m1767
 */
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class ZuulApp {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApp.class,args);
    }
}

5.5 结果演示
  • 通过访问这个 api-xxx 路径来访问
  • 在这里插入图片描述
5.6 小笔记
  • 网关通过设置路由,来确定每个路径去向哪个服务器,从而实现对每个服务的把控。

6. 解决雪崩效应

6.1 添加依赖
  • 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>org.example</groupId>
        <artifactId>springcloud-test-feign-order</artifactId>
        <version>1.0-SNAPSHOT</version>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.2.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</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>Dalston.RC1</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>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>
    
    </project>
    
6.2 配置文件
  • application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:9999/eureka/
    server:
      port: 9765
      tomcat:
        max-threads: 50
    spring:
      application:
        name: service-order-feign
    
    feign:
      hystrix:
        enabled: true
    
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 4000
    
6.3 使用Feign 重写service层和控制层,以及添加fallback
  • feign是 是Netflix开发的声明式,模板化的HTTP客户端 ,能更加优雅的调用rest api同restTemplate

  • Hystrix 叫做断路器/熔断器。微服务系统中,整个系统出错的概率非常高,因为在微服务系统中,涉及到的模块太多了,每一个模块出错,都有可能导致整个服务出现故障,当所有模块都稳定运行时,整个服务才算是稳定运行。

  • controller

    package com.zsl.controller;
    
    import com.zsl.service.MemberFeign;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    /**
     * @author m1767
     */
    @RestController
    public class OderFeignController {
        @Autowired
        private MemberFeign memberFeign;
    
        @RequestMapping("/getOderByUserList")
        public List<String> getOderByUserList(){
            System.out.println("掉用service-member服务");
            return memberFeign.getOderByUserList();
        }
    
        @RequestMapping("/getInfo")
        public String getInfo(){
            return "info";
        }
    }
    
    
  • service

    package com.zsl.service;
    
    import com.zsl.fallback.FallBack;
    import org.springframework.cloud.netflix.feign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author m1767
     */
    @FeignClient(value = "service-member",fallback = FallBack.class)
    public interface MemberFeign {
    
        /**
         * 获取用户 list
         * @return 用户列表
         */
        @RequestMapping("/getMember")
        public List<String> getOderByUserList();
    }
    
    
  • fallback

    package com.zsl.fallback;
    
    import com.zsl.service.MemberFeign;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author m1767
     */
    @Component
    public class FallBack implements MemberFeign {
        @Override
        public List<String> getOderByUserList() {
            List<String> map = new ArrayList<>();
            map.add("no order list");
            System.out.println("服务器发生异常..............");
            return map;
        }
    }
    
    
6.4 启动
package zsl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

/**
 * @author m1767
 */
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class FeignApp {
    public static void main(String[] args) {
        SpringApplication.run(FeignApp.class,args);
    }
}

6.5 演示
  • 改造会员服务的service代码,每次请求睡眠三秒,创建雪崩效应场景。

  • 在这里插入图片描述

  • 使用压力测试

  • 同时发送51次请求

  • 在这里插入图片描述

  • 最终展示结果是:访问/getInfo连接不影响,而有的 访问/getOderByUserList的请求会被段掉,调用fallback

  • .测试的时候,刷新浏览器,最终返回本地服务。

  • 在这里插入图片描述

  • 测试的请求,有的也被返回本地服务

  • 在这里插入图片描述

6.6 小笔记
  • 使用Feign,以接口的形式调用rest api

  • 使用hytrix 解决服务器的雪崩效应。

    • 四个机制:

        1. 隔离(线程池隔离和信号量隔离):限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

        2. 降级:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。

        3. 熔断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值