springboot整合springcloud的eureka、配置中心、服务调用、Hystrix、Zuul网关

前言:springboot整合springcloud的eureka、配置中心、服务调用、Hystrix、Zuul网关
在这里插入图片描述

项目结构:
在这里插入图片描述

一、环境准备

1、创建maven父工程,并导入依赖

<properties>
     <project-build-sourceEncoding>UTF-8</project-build-sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
     <java.version>1.8</java.version>
     <maven-compiler.source>1.8</maven-compiler.source>
     <maven-compiler.target>1.8</maven-compiler.target>
     <junit-version>4.12</junit-version>
 </properties>

 <dependencyManagement>
     <dependencies>
         <!--springcloud的依赖-->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>Greenwich.SR1</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
         <!--springboot的依赖-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-dependencies</artifactId>
             <version>2.1.4.RELEASE</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
         <!--数据库的依赖-->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.47</version>
         </dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid</artifactId>
             <version>1.1.22</version>
         </dependency>
         <!--springboot启动器-->
         <dependency>
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
             <version>2.1.1</version>
         </dependency>
         <!--junit-->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>${junit-version}</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-core</artifactId>
             <version>1.2.3</version>
         </dependency>
         <!--lombok-->
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <version>1.18.18</version>
         </dependency>
         <!--log4j日志-->
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
             <version>1.2.17</version>
         </dependency>
     </dependencies>
 </dependencyManagement>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

二、Eureka注册中心

1、Eureka单机模式

1.1、创建maven子工程(服务),并导入依赖

<!--导入父工程依赖-->
<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>

 <!--导入项目依赖-->
<dependencies>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

1.2、创建application.yaml配置文件

server:
  port: 7001

#Eureka的配置
eureka:
  instance:
    hostname: springcloud-eureka  #Eureka服务端的实例名称(如果配置集群,此处不能写localhost或127.0.0.1)
  client:
    register-with-eureka: false # 表示是否想eureka注册中心注册自己
    fetch-registry: false  #结果为false表示自己为注册中心
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

1.3、开启eureka服务注册功能

@SpringBootApplication
@EnableEurekaServer  //服务端的启动类,可以接受别人注册进来
public class SpringCloudEurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class,args);
    }
}

在这里插入图片描述

2、eureka集群模式

2.1、改造单机模式

修改application.yaml文件
注:集群模式下eureka.instance.hostname属性不能写localhost或127.0.0.1

server:
  port: 7001

#Eureka的配置
eureka:
  instance:
    hostname: springcloud-eureka  #Eureka服务端的实例名称(如果配置集群,此处不能写localhost或127.0.0.1)
  client:
    register-with-eureka: false # 表示是否想eureka注册中心注册自己
    fetch-registry: false  #结果为false表示自己为注册中心
    service-url:
      defaultZone: http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #监控页面

2.2、创建maven子工程(eureka2)

2.2.1、步骤参照eureka单机模式
2.2.2、修改application.yaml文件
server:
  port: 7002

#Eureka的配置
eureka:
  instance:
    hostname: springcloud-eureka02  #Eureka服务端的实例名称(如果配置集群,此处不能写localhost或127.0.0.1)
  client:
    register-with-eureka: false # 表示是否想eureka注册中心注册自己
    fetch-registry: false  #结果为false表示自己为注册中心
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka03:7003/eureka/   #监控页面

2.3、创建maven子工程(eureka3)

2.3.1、步骤参照eureka单机模式
2.3.2、修改application.yaml文件
server:
  port: 7003

#Eureka的配置
eureka:
  instance:
    hostname: springcloud-eureka03  #Eureka服务端的实例名称(如果配置集群,此处不能写localhost或127.0.0.1)
  client:
    register-with-eureka: false # 表示是否想eureka注册中心注册自己
    fetch-registry: false  #结果为false表示自己为注册中心
    service-url:
      defaultZone: http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka:7001/eureka/   #监控页面

2.4、修改hosts配置文件

添加:

  • 127.0.0.1 springcloud-eureka
  • 127.0.0.1 springcloud-eureka02
  • 127.0.0.1 springcloud-eureka03
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCPIP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	1             localhost
127.0.0.1       activate.navicat.com
#添加如下配置
127.0.0.1  springcloud-eureka
127.0.0.1  springcloud-eureka02
127.0.0.1  springcloud-eureka03

2.5、分别启动eureka服务

eureka01服务
eureka02服务
eureka03服务

三、springcloud配置中心

1、在远程服务(github)创建配置文件

在这里插入图片描述

2、创建配置中心服务端

2.1、创建maven子工程,导入依赖

<!--导入父工程依赖-->
<parent>
   <artifactId>springcloud-001</artifactId>
   <groupId>com.springcloud</groupId>
   <version>1.0-SNAPSHOT</version>
   <relativePath>../pom.xml</relativePath>
</parent>

<!--导入项目依赖-->
<dependencies>
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-config-server</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-actuator</artifactId>
   </dependency>
</dependencies>

2.2、创建application.yaml文件

server:
  port: 3344
spring:
  application:
    name: springcloud-config-service
    #连接远程仓库
  cloud:
    config:
      server:
        git:
          uri: https://github.com/ces/git_test01.git
          username: 用户名  #github用户名
          password: 密码 #github用户密码

2.3、启动服务

@SpringBootApplication
@EnableConfigServer  //开启远程配置服务
public class SpringCloudConfigService3344 {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConfigService3344.class,args);
    }
}

访问方式:/{label}/{name}-{profile}.想要展示的文件类型,即/节点/文件名-环境/
如:http://127.0.0.1:3344/master/spring_config-dev.json
在这里插入图片描述

3、创建配置中心客户端

3.1、创建maven子工程,导入依赖

<!--导入父工程依赖-->
<parent>
   <artifactId>springcloud-001</artifactId>
   <groupId>com.springcloud</groupId>
   <version>1.0-SNAPSHOT</version>
   <relativePath>../pom.xml</relativePath>
</parent>

<!--导入项目依赖-->
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</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-actuator</artifactId>
    </dependency>
</dependencies>

3.2、创建配置文件

application.yaml

#用户级别的配置
spring:
  application:
    name: springcloud-config-client3355
server:
  port: 3355

bootstrap.yml

#系统级别的配置
spring:
  cloud:
    config:
      uri: http://localhost:3344
      name: spring_config  #从远程仓库上读取的资源名称,不需要后缀名
      profile: dev
      label: master  #指定被读取资源所在节点名称

3.3、创建controller类(便于测试)

@RestController
public class ConfigClientController {

    @Value("${spring.application.name}")  //获取远程配置文件的属性值
    private String applicationName;

    @Value("${eureka.service}")   //获取远程配置文件的属性值
    private String eurekaService;

    @Value("${server.port}")    //获取远程配置文件的属性值
    private String port;

    @RequestMapping("/getConfig")
    public String getConfig(){
        return "applicatin:" + applicationName +
                " eurekaService:" + eurekaService +
                " port:" + port;

    }
}

3.4、启动客户端测试

@SpringBootApplication
public class ConfigClient_3355 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClient_3355.class,args);
    }
}

在这里插入图片描述

四、服务调用

1、概括

spring cloud的 Netflix 中提供了两个组件实现负载均衡调用:ribbonfeign

  • Ribbon:是一个基于 HTTP 和 TCP 客户端 的负载均衡的工具。Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。启动类注解Ribbon是 @RibbonClient

  • Feign:是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。采用接口的方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方法即可, 不需要自己构建http请求。启动类注解feign的是 @EnableFeignClients

1.1、 区别

  • 1、协议
    Dubbo:支持多传输协议(Dubbo、Rmi、http、redis等等),可以根据业务场景选择最佳的方式。非常灵活。默认的Dubbo协议:利用Netty,TCP传输,单一、异步、长连接,适合数据量小、高并发和服务提供者远远少于消费者的场景。
    Feign:基于Http传输协议,短连接,不适合高并发的访问。

  • 2、负载均衡
    Dubbo: 支持4种算法(随机、轮询、活跃度、Hash一致性),而且算法里面引入权重的概念。配置的形式不仅支持代码配置,还支持Dubbo控制台灵活动态配置。负载均衡的算法可以精准到某个服务接口的某个方法。
    Feign: 只支持N种策略:轮询、随机、ResponseTime加权。负载均衡算法是Client级别的。

  • 3、容错策略
    Dubbo: 支持多种容错策略:failover、failfast、brodecast、forking等,也引入了retry次数、timeout等配置参数。
    Feign: 利用熔断机制来实现容错的,处理的方式不一样。

注:以下均基于整合mybatis测试

2、创建服务提供端

2.1、创建maven子工程,并导入依赖

<!--导入父工程依赖-->
<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>

<!--导入项目依赖-->
<dependencies>
    <!--完善监控信息-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
    </dependency>
    <!--test-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--jetty-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2.2、创建pojo类

@Data
@NoArgsConstructor
@Accessors(chain = true) //开启支持链式写法
public class Dept implements Serializable {

    private int id;
    private String dname;

    private String dbSource;

    public Dept(String dname){
        this.dname = dname;
    }
}

2.3、创建dao接口类

@Mapper  //org.apache.ibatis.annotations.Mapper
@Repository
public interface DeptDao {

    List<Dept> findList();

    Dept findById(int id);
}

2.4、创建service接口类

public interface DeptService {
    List<Dept> findList();

    Dept findById(int id);
}

2.5、创建service接口实现类

@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    DeptDao deptDao;

    public List<Dept> findList() {
        return deptDao.findList();
    }

    public Dept findById(int id) {
        return deptDao.findById(id);
    }
}

2.6、创建dao的mapper文件

在目录resources/mybatis/mapper创建

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.provicer.dao.DeptDao">
    <select id="findList" resultType="dept">
        select * from dept
    </select>

    <select id="findById" parameterType="int" resultType="dept">
        select * from dept where id = #{id}
    </select>
</mapper>

2.7、创建mybatis-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--此文件可有可无-->
<configuration>
    <!--开启二级缓存-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

2.8、创建application.yaml文件

server:
  port: 8081

mybatis:
  type-aliases-package: com.api.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml
  config-location: classpath:mybatis/mybatis-config.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    driver-class-name: com.mysql.jdbc.Driver
    password: 123456
    url: jdbc:mysql://localhost:3306/spring_cloud_test?useUnicode=true&characterEncoding=utf8&useSSL=false&useSSL=false&serverTimezone=UTC


#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #注册地址
  instance:
    instance-id: springcloud-provider-dept  #修改eureka上的默认描述

#点击eureka的描述,显示信息
info:
  app.name: springcloud-provider
  company.name: zyhlwgs

2.9、创建启动类并启动应用

@SpringBootApplication
@EnableEurekaClient  //在服务启动后,自动注册到Eureka中
@EnableDiscoveryClient  //服务发现
public class SpringCloudProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudProviderApplication.class,args);
    }
}

3、Ribbon服务调用

3.1、创建maven子工程,并导入依赖

<!--导入父工程依赖-->
<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>

<!--导入项目依赖-->
<!--消费者  实体类+web -->
<dependencies>
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--从eureka中发现服务-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

3.2、自定义负载均衡策略(默认是轮询),可选

public class RandomRule extends AbstractLoadBalancerRule {
    //每个服务,访问5次,换下一个服务(3个)

    //total=0,默认=0,如果=5,我们指向下一个服务点
    //index=0,默认=0,如果total=5,则index+1
    private int total = 0;  //被调用的次数
    private int index = 0;  //服务节点


    public RandomRule() {
    }

    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;

            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }

                List<Server> upList = lb.getReachableServers();  //获得活着的服务
                List<Server> allList = lb.getAllServers();  //获得全部的服务
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }

                /*源码:
                int index = this.chooseRandomInt(serverCount);  //生成区间随机数
                server = (Server)upList.get(index);  //从活着的服务中随机获取一个服务*/

                //改造上面注释源码
                if (total<5){
                    server = upList.get(index);
                    total++;
                } else {
                    total = 0;
                    index++;
                    if (index > upList.size()){
                        index = 0;
                    }
                    server = upList.get(index);
                }

                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }

                    server = null;
                    Thread.yield();
                }
            }

            return server;
        }
    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }

    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}

3.3、将自定义负载均衡策略类注入spring容器中

@Configuration
public class MyRibbon {

    @Bean
    public IRule getRule() {
        return new RandomRule();  //默认是轮询,现在我们自定义了算法
    }
}

3.4、实现ribbon负载均衡

@Configuration
public class ConsumerConfig {

    @Bean
    @LoadBalanced  //实现ribbon负载均衡
    public RestTemplate getRestTemplate(){
        return  new RestTemplate();
    }
}

3.5、创建controller类调用服务

@RestController
public class DeptConsumerController {

    @Autowired
    RestTemplate restTemplate;

    //private final String PREFIX_URL = "http://localhost:8081/";
    private final String PREFIX_URL = "http://SPRINGCLOUD-PROVIDER-DEPT/";

    @RequestMapping("/findList")
    public List<Dept> findList(){
        return restTemplate.getForObject(PREFIX_URL + "findList",List.class);
    }

    @RequestMapping("/findById/{id}")
    public Dept findById(@PathVariable("id") int id){
        return restTemplate.getForObject(PREFIX_URL + "findById/"+id,Dept.class);
    }
}

3.6、在启动类中开启ribbon功能,并启动

@SpringBootApplication
@EnableEurekaClient
//在微服务启动的时候就能自动加载我们自定义的Ribbon类
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRibbon.class)
public class SpringConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringConsumerApplication.class,args);
    }
}

4、Feign服务调用

4.1、创建api子工程

4.1.1、创建maven子工程,并导入依赖
<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
</dependencies>

4.1.2、创建feign接口
@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptFeignService {

    @GetMapping("/findList")
    List<Dept> findList();

    @GetMapping("/findById/{id}")
    Dept findById(@PathVariable("id") int id);
}

4.2、创建服务调用工程

4.2.1、创建maven子工程,并导入依赖
<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<!--消费者  实体类+web -->
<dependencies>
    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--从eureka中发现服务-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>
4.2.2、创建controller接口调用类
@RestController
public class DeptConsumerController {

    @Autowired
    DeptFeignService service;

    @GetMapping("/findList")
    public List<Dept> findList(){
        return service.findList();
    }

    @RequestMapping("/findById/{id}")
    public Dept findById(@PathVariable("id") int id){
        return service.findById(id);
    }
}

4.2.3、创建application.yaml文件
server:
  port: 8090

#配置eureka
eureka:
  client:
    register-with-eureka: false  #不向eureka中注册自己
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #注册地址

4.2.4、在启动类中开启feign功能,并启动
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.api"})
@ComponentScan({"com.api","com.consumer"})
public class SpringConsumerFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringConsumerFeignApplication.class,args);
    }
}

五、Hystrix

  • 分布式面临的问题:复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败!(网络断开)
  • 服务雪崩:多个服务之间调用的时候,假设服务A调用服务B和服务C,服务B和服务C又调用其他的微服务,这就是所谓的“扇出”,如果扇出的链路上,某个微服务的调用响应时间过长或者服务不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统奔溃,这就是所谓的“雪崩效应”。我们需要“弃车保帅”!

1、概括

Hystrix是一个用于处理分布式系统延迟和容错开源库,在分布式系统里,许多依赖不可避免的出现调用失败,比如超时或者异常等等。Hystrix能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性

  • 服务熔断(服务端)
  • 服务降级(客户端)
  • 服务限流
  • 实时监控

服务正常时:
在这里插入图片描述
服务异常时:
在这里插入图片描述
流量高峰时,一个单节点的宕机或延迟,会迅速导致所有服务负载达到饱和。应用中任何一个可能通过网络访问其他服务的节点,都有可能成为造成潜在故障的来源。更严重的是,还可能导致服务之间的延迟增加,占用队列、线程等系统资源,从而导致多系统之间的级联故障。
在这里插入图片描述

2、服务熔断

2.1、创建maven子工程,并导入依赖

<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--完善监控信息-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
    </dependency>
    <!--test-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--jetty-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

2.2、整合mybatis(参考上面服务提供端的步骤)

2.3、创建application.yaml文件

server:
  port: 8084

mybatis:
  type-aliases-package: com.api.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml
  config-location: classpath:mybatis/mybatis-config.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    driver-class-name: com.mysql.jdbc.Driver
    password: 123456
    url: jdbc:mysql://localhost:3306/spring_cloud_test03?useUnicode=true&characterEncoding=utf8&useSSL=false&useSSL=false&serverTimezone=UTC


#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #注册地址
  instance:
    instance-id: springcloud-provider-dept-hystrix  #修改eureka上的默认描述

#点击eureka的描述,显示信息
info:
  app.name: springcloud-provider-dept-hystrix
  company.name: zyhlwgs


2.4、修改controller类

@RestController
public class DeptController {

    @Autowired
    DeptServiceImpl deptService;

    @GetMapping("/findById/{id}")
    @HystrixCommand(fallbackMethod = "hystrixGet")  //服务熔断调用
    public Dept findById(@PathVariable("id") int id) {
        Dept dept = deptService.findById(id);
        if (dept == null) {
            throw new RuntimeException("id->"+id+":不存在该用户,或者信息无法查询到!");
        }
        return dept;
    }

   //备选方案,熔断
    public Dept hystrixGet(@PathVariable("id") int id){
        return new Dept()
                .setId(id)
                .setDname("id->"+id+":没有查询到对应的信息,null+@hystrix")
                .setDbSource("no data in database");
    }

}

2.5、修改启动类,测试

@SpringBootApplication
@EnableEurekaClient  //开启自动注册
@EnableDiscoveryClient  //服务发现
@EnableCircuitBreaker  //开启熔断的支持
public class SpringCloudProvicerHystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudProvicerHystrixApplication.class,args);
    }
}

在这里插入图片描述

3、服务降级(feign服务)

3.1、修改Feign服务的application.yaml,开启降级功能

#开启降级支持
feign:
  hystrix:
    enabled: true

3.2、在feign服务中的api服务,创建降级类

在这里插入图片描述

//服务降级
@Component
public class DeptFeignFallBackFactory implements FallbackFactory {
    @Override
    public DeptFeignService create(Throwable throwable) {
        return new DeptFeignService() {
            @Override
            public List<Dept> findList() {
                return null;
            }

            @Override
            public Dept findById(int id) {
                return new Dept()
                        .setId(id)
                        .setDname("id->"+id+":没有对应的信息,客户端提供了降级的信息,此服务已被关闭")
                        .setDbSource("没有数据~");
            }
        };
    }
}

3.3、feign调用引入降级方法

@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptFeignFallBackFactory.class)
public interface DeptFeignService {

    @GetMapping("/findList")
    List<Dept> findList();

    @GetMapping("/findById/{id}")
    Dept findById(@PathVariable("id") int id);
}

3.4、启动服务测试

在这里插入图片描述

4、实时监控

4.1、创建maven子工程,并导入依赖

<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--从eureka中发现服务-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

4.2、创建application.yaml文件

server:
  port: 9001
spring:
  application:
    name: hystrix-dashboard

#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #注册地址
  instance:
    instance-id: hystrix-dashboard  #修改eureka上的默认描述

4.3、创建启动类,并开启监控功能

@SpringBootApplication
@EnableHystrixDashboard  //开启监控
public class HystrixDashBoardApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashBoardApplication.class,args);
    }
}

4.4、修改服务熔断子工程

4.4.1、修改启动类
@SpringBootApplication
@EnableEurekaClient  //开启自动注册
@EnableDiscoveryClient  //服务发现
@EnableCircuitBreaker  //开启熔断的支持
public class SpringCloudProvicerHystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudProvicerHystrixApplication.class,args);
    }
	//添加如下方法
    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet(){
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        servletRegistrationBean.addUrlMappings("/actuator/hystrix.stream");
        return servletRegistrationBean;
    }
}

4.5、分别启动eureka、服务熔断服务、服务监控服务

访问:http://localhost:9001/hystrix
在这里插入图片描述

4.6、测试

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

六、zuul路由网关

经由zuul网关访问各个服务

1、创建maven子工程,并导入依赖

<parent>
    <artifactId>springcloud-001</artifactId>
    <groupId>com.springcloud</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
    <!--zuul-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--从eureka中发现服务-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.api</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

2、创建application.yaml文件

server:
  port: 9527

spring:
  application:
    name: springcloud-zuul

eureka:
  client:
    service-url:
      defaultZone: http://springcloud-eureka:7001/eureka/,http://springcloud-eureka02:7002/eureka/,http://springcloud-eureka03:7003/eureka/   #注册地址
  instance:
    instance-id: springcloud-zuul-9527
    prefer-ip-address: true #隐藏IP

info:
  app.name: test-zuul
  company.name: ces

zuul:
  routes:
    mydept: springcloud-provider-dept
    mydept.path: /mydept/**  #  /mydept/** 替换 springcloud-provider-dept
  ignored-services: springcloud-provider-dept  #不能使用这个路径访问
  #ignored-services: "*"  #隐藏全部的访问路径
  prefix: /ces  #设置公共的访问前缀

3、创建启动类,并启动测试

@SpringBootApplication
@EnableZuulProxy
public class SpringCloudZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudZuulApplication.class,args);
    }
}

在这里插入图片描述

完成!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值