SpringCloud 微服务 初学习仅试验 理论待更新(Eureka Ribbon Feign Hystrix Zuul))

微服务条目技术
服务开发SpringBoot, Sprin,g SpringMVC
服务注册与发现Eureka, Consul, Zookerrper
服务调用Rest, RPC, gRPC
服务熔断器Hystrix, Envoy
负载均衡Ribbon, Nginx
服务器接口调用Feign
消息队列Kafka, RabbitMQ, ActiveMQ
服务配置中心管理SpringCloudConfig
服务路由(API网关)Zuul

依赖版本

依赖版本
SpringCloudHoxton.SR8
SpringBoot2.3.3.RELEASE
spring-cloud-starter-netflix-eureka-client2.2.5.RELEASE
spring-cloud-starter-netflix-eureka-server2.2.5.RELEASE
spring-cloud-starter-netflix-ribbon2.2.5.RELEASE
spring-cloud-starter-openfeign2.2.5.RELEASE
spring-cloud-starter-netflix-hystrix2.2.5.RELEASE
spring-cloud-starter-netflix-hystrix-dashboard2.2.5.RELEASE
spring-cloud-starter-netflix-zuul2.2.5.RELEASE

项目地址https://gitee.com/handc/spring_cloud.git

1.Eureka

1.1 新建Maven工程 导入依赖

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <dependency>
            <!--springcloud的依赖-->
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
        </dependency>

        <!--SpringBoot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.5.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.10</version>
        </dependency>

        <!--SpringBoot 启动器-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--日志和测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
</dependencyManagement>

1.2 消费者服务接口

在项目下新建模块springcloud-api

1.2.1 导入依赖

    <!--当前Module自己需要的依赖 如果依赖中已经配置 就可以不写-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

1.2.2 新建Student实体类

@Data
@NoArgsConstructor //提供无参构造方法
@Accessors(chain = true) //链式写法
public class Student implements Serializable {

    private Long id;
    private String name;

    private String db_name; //那个数据库的数据
    public Student(String name) {
        this.name = name;
    }
}

1.2.3 StudentService

@Component
public interface StudentClientService {

    @GetMapping("/stu/get/{id}")
    public Student queryById(@PathVariable("id") Long id);

    @GetMapping("/stu/list")
    public List<Student> queryAll();

    @PostMapping("/stu/add")
    public boolean addStudent(Student student);
}

1.3 数据库

新建三个数据库 db01 db02 db03

三个数据库建立相同的表, 相同的数据

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for student1
-- ----------------------------
DROP TABLE IF EXISTS `student1`;
CREATE TABLE `student1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `db_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student1
-- ----------------------------
INSERT INTO `student1` VALUES ('1', 'zhang', DATABASE());
INSERT INTO `student1` VALUES ('2', 'li', DATABASE());
INSERT INTO `student1` VALUES ('3', 'wang', DATABASE());
INSERT INTO `student1` VALUES ('4', 'zhao', DATABASE());
INSERT INTO `student1` VALUES ('5', 'jiang',DATABASE());

1.4 Eureka 注册与服务发现中心

为了方便区分 先修改hosts文件 C:\Windows\System32\drivers\etc\hosts

在后面增加

127.0.0.1 eureka8801.com
127.0.0.1 eureka8802.com
127.0.0.1 eureka8803.com

项目下新建模块 springcloud-eureka-8801

1.4.1 导入依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>

1.4.2 编写配置 application.yml

server:
  port: 8801

# eureka配置
eureka:
  instance:
    hostname: eureka8801.com

  client:
    register-with-eureka: false # 是否向注册中心注册自己
    fetch-registry: false  #  #fetch-registry如果 false 则表示自己为注册中心
    service-url:
      # 单机
      defaultZone: http://eureka8801.com:8801/eureka/

1.4.3 创建启动类EurekaServer_8801


@SpringBootApplication
@EnableEurekaServer //Eureka服务端启动类 可以接收别人注册进来
public class EurekaServer_8801 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_8801.class,args);
    }
}

同时启动springcloud-provider-student-8001 和 springcloud-eureka-8801

image-20201125210255365

1.5 服务提供者

项目下新建模块 springcloud-provider-student-8001

1.5.1 导入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>

    <!--拿到实体类 api ,module-->
    <dependency>
        <groupId>com.handc</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</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>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <!--test-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</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-netflix-eureka-client</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <!--完善监控信息-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <version>2.1.4.RELEASE</version>
    </dependency>

</dependencies>

1.5.2 配置yml

# 端口
server:
  port: 8001

#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
    username: root
    password: admin

# mybatis配置
mybatis:
  type-aliases-package: com.huan.springcloud.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

#Eurka配置
eureka:
  instance:
    instance-id: springcloud-provider-dept8001 # 修改Eureka上的默认描述信息
  client:
    register-with-eureka: true   #表示是否向注册中心注册自己
    fetch-registry: true         #fetch-registry如果 false 则表示自己为注册中心
    service-url:  #监控页面
      defaultZone: http://eureka8801:8801/eureka/

# info 配置
info:
  app.name: handc-springcloud
  company.name: blog.handc

1.5.3 编写服务提供

Studentservice
public interface StudentService {

    public Student queryById(@PathVariable("id") Long id);
    
    public List<Student> queryAll();
    public boolean addStudent(Student student);
}
StudentServiceImpl 实现类
@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentDao studentDao;

    public Student queryById(Long id) {
        return studentDao.queryById(id);
    }

    public List<Student> queryAll() {
        return studentDao.queryAll();
    }

    public boolean addStudent(Student student) {
        return studentDao.addStudent(student);
    }
}
持久层StudentDao
@Mapper
@Repository
public interface StudentDao {
    public Student queryById(Long id);
    public List<Student> queryAll();
    public boolean addStudent(Student student);
}
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.handc.springcloud.dao.StudentDao">
    <select id="queryById" resultType="Student" parameterType="Long">
        select * from student1 where id=#{id};
    </select>

    <select id="queryAll" resultType="Student">
        select * from student1;
    </select>
    <insert id="addDept" parameterType="Student">
        insert into student1 (name,db_name)
         values (#{name},DATABASE());
    </insert>

</mapper>
控制层
@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/stu/get/{id}")
    public Student getById(@PathVariable("id") Long id){
        return studentService.queryById(id);
    }

    @PostMapping("/stu/add")
    public boolean addStudent(Student student){
        return studentService.addStudent(student);
    }

    @GetMapping("/stu/list")
    public List<Student> list(){
        return studentService.queryAll();
    }
}

1.6 编写启动类

@SpringBootApplication
@EnableEurekaClient // 服务启动后自动注册到Eureka
@EnableDiscoveryClient
public class StudentProvider8001 {
    public static void main(String[] args) {
        SpringApplication.run(StudentProvider8001.class,args);
    }
}

1.7 集群配置

1.7.1 三个注册中心

按照配置springcloud-eureka-8801 方法

新建模块springcloud-eureka-8802 springcloud-eureka-8803

注意: 修改xml 其他不变

在8801中 需要关联8802和2203,同样 对8802和8803进行修改

#Eurka配置
eureka:
  instance:
    instance-id: springcloud-provider-student8001 # 修改Eureka上的默认描述信息
  client:
    register-with-eureka: true   #表示是否向注册中心注册自己
    fetch-registry: true         #fetch-registry如果 false 则表示自己为注册中心
    service-url:  #监控页面
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/
    service-url:
      # 集群
      defaultZone: http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/

1.7.2 三个服务提供者

将springcloud-provider-student-8001

复制2份 springcloud-provider-student-8002 springcloud-provider-student-8003

注意修改xml 以8002为例 注意需要同时注册到三个注册中心

# 端口
server:
  port: 8002

#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
    username: root
    password: admin

# mybatis配置
mybatis:
  type-aliases-package: com.handc.springcloud.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

#Eurka配置
eureka:
  instance:
    instance-id: springcloud-provider-dept8002 # 修改Eureka上的默认描述信息
  client:
    register-with-eureka: true   #表示是否向注册中心注册自己
    fetch-registry: true         #fetch-registry如果 false 则表示自己为注册中心
    service-url:  #监控页面
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/

# info 配置
info:
  app.name: handc-springcloud
  company.name: blog.handc

1.7.3 测试

同时启动三个注册中心 和三个服务提供者

image-20201128100106981

2. 服务消费者 Ribbon+RestTemplate

2.1 服务消费者

新建模块 springcloud-consumer-dept-80

2.1.1 导入依赖

<dependencies>

        <!--实体类-->
        <dependency>
            <groupId>com.handc</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>
            <version>2.2.5.RELEASE</version>
        </dependency>
    	<!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

    </dependencies>

2.1.2 编写application.yml

server:
  port: 80

  #Eurka配置
eureka:
  client:
    register-with-eureka: false   #表示是否向注册中心注册自己
    service-url:  # 客户端可以从这三个里面取
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/

2.2 定义一个ConfigBean

@Configuration
public class ConfigBean { //@Configuration  ---->Spring applicationContext.xml

    // 配置负载均衡 实现restTemplate
    // IRule
    // RoundRobinRule 轮询
    // RandomRule 随机
    // RetryRule 先按照轮询获取, 如果获取失败 则会在指定时间内进行重试
    // AvailabilityFilteringRule : 先过滤掉崩溃的服务(跳闸的服务, ) 对剩下的进行轮询

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2.3 定义controller类

@RestController
public class DeptConsumerController {

    @Autowired
    private RestTemplate restTemplate; //提供多种便捷访问远程http服务的方法,简单的restful服务模版
    //通过Ribbon实现时候 这里地址是一个变量, 通过服务名来访问
    private static final String REST_URL_PREFIX="http://SPRINGCLOUD-PROVIDER-DEPT";


    @RequestMapping("/consumer/stu/add")
    public boolean add(Student student){
        return restTemplate.postForObject(REST_URL_PREFIX+"/stu/add/",student,Boolean.class);
    }

    @RequestMapping("/consumer/stu/get/{id}")
    public Student get(@PathVariable("id") Long id){
        return restTemplate.getForObject(REST_URL_PREFIX+"/stu/get/"+id,Student.class);
    }

    @RequestMapping("/consumer/stu/list")
    public List<Student> list(){
        return restTemplate.getForObject(REST_URL_PREFIX+"/stu/list/",List.class);
    }

}

2.4 编写启动类

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

同时启动 注册中心8801 8802 8803 最少一个

启动服务提供者8001 8002 8003

启动服务消费者80 发出请求可以看出 通过riibbon负载均衡到不同服务提供者

image-20201128101358990image-20201128101410416

3. Feign

新建模块 springcloud-consumer-dept-feign

3.1 导入依赖

<dependencies>
        <!--实体类-->
        <dependency>
            <groupId>com.handc</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>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
    </dependencies>

3.2 添加application.yml配置

server:
  port: 80

  #Eurka配置
eureka:
  client:
    register-with-eureka: false   #表示是否向注册中心注册自己
    service-url:  # 客户端可以从这三个里面取
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/

3.3 ConfigBean

@Configuration
public class ConfigBean { //@Configuration  ---->Spring applicationContext.xml

    // 配置负载均衡 实现restTemplate
    // IRule
    // RoundRobinRule 轮询
    // RandomRule 随机
    // RetryRule 先按照轮询获取, 如果获取失败 则会在指定时间内进行重试
    // AvailabilityFilteringRule : 先过滤掉崩溃的服务(跳闸的服务, ) 对剩下的进行轮询

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3.4 定义controller类

@RestController
public class DeptConsumerController {

    @Autowired
    private StudentClientService studentClientService;


    @RequestMapping("/consumer/stu/add")
    public boolean add(Student student){
        return this.studentClientService.addStudent(student);
    }

    @RequestMapping("/consumer/stu/get/{id}")
    public Student get(@PathVariable("id") Long id){
        return this.studentClientService.queryById(id);
    }

    @RequestMapping("/consumer/stu/list")
    public List<Student> list(){
        return this.studentClientService.queryAll();
    }
}

3.5 编写启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients("com.handc.springcloud")
public class feignStudentConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(feignStudentConsumer_80.class,args);
    }
}

同时启动 注册中心8801 8802 8803 最少一个

启动服务提供者8001 8002 8003

启动服务消费者feign-80 发出请求可以看出 通过riibbon负载均衡到不同服务提供者

4. Hystrix

服务熔断:   服务端  某个服务超时或者异常会引起异常,相当于保险丝

服务降级:   客户端  从整体网站负载考虑~ 当某个服务熔断或者关闭之后, 服务将不在被调用,
                    用户可以发出请求,但是请求不会到服务器
                    此时在客户端准备一个自己的失败回调 FallbackFactory 返回一个默认的值(缺省值)
                    整体服务水平下降

4.1 服务熔断

新建模块springcloud-provider-dept-8001-hystrix

4.1.1 导入依赖

  <dependencies>
        <!--拿到实体类 api ,module-->
        <dependency>
            <groupId>com.handc</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</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>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</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-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--完善监控信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

    </dependencies>

4.2.2 编写配置application.yml

# 端口
server:
  port: 8001

#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
    username: root
    password: admin

# mybatis配置
mybatis:
  type-aliases-package: com.handc.springcloud.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

#Eurka配置
eureka:
  instance:
    instance-id: springcloud-provider-hystrix-dept8001 # 修改Eureka上的默认描述信息
  client:
    register-with-eureka: true   #表示是否向注册中心注册自己
    fetch-registry: true         #fetch-registry如果 false 则表示自己为注册中心
    service-url:  #监控页面
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/

# info 配置
info:
  app.name: handc-springcloud
  company.name: blog.handc

4.2.3 controller层增加熔断机制@HystrixCommand

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/stu/get/{id}")
    //一旦调用服务方法失败抛出 错误信息后 自动调用@HystrixCommand标注好的fallbackMethod指定的方法
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public Student getById(@PathVariable("id") Long id) {
        Student student = studentService.queryById(id);
        //模拟查询异常
        if (student == null) {
            throw new RuntimeException("id: " + id + "不存在该用户,或者无法找到信息");

        }
        return student;

    }

    //备选方法
    public Student hystrixGet(Long id) {
        return new Student()
                .setDeptno(id)
                .setDname("id: " + id + "没有对应的信息, null---->@Hystrix")
                .setDb_source("no this databases in MySQL");
    }   
}

4.2.4 主启动类添加注解 @EnableCircuitBreaker

//启动类
@SpringBootApplication
@EnableEurekaClient  //在服务启动后自动注册到Eureka中
@EnableDiscoveryClient
//添加对熔断的支持
@EnableCircuitBreaker
public class DeptProviderHystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProviderHystrix_8001.class,args);
    }
}

启动 注册中心springcloud-eureka-8801,

服务提供者 springcloud-provider-dept-8001-hystrix

最后启动服务消费者springcloud-consumer-dept-80

服务访问 正常 http://localhost/consumer/stu/get/2

image-20201128141745729

访问 http://localhost/consumer/stu/get/20 出现服务熔断

image-20201128141821756

4.2 服务降级

4.2.1 导入依赖

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

4.2.2 消费者服务springcloud-api

StudentClientServiceFallbackFactory 实现FallbackFactory接口

//服务降级
@Component
public class StudentClientServiceFallbackFactory implements FallbackFactory {
    public Object create(Throwable throwable) {
        return new StudentClientService() {
            public Student queryById(Long id) {
                return new Student()
                        .setId(id)
                        .setName("id==>"+id+"没有对应的信息,客户端提供降级信息,这个服务已经关闭")
                        .setDb_name("没有数据");
            }

            public List<Student> queryAll() {
                return null;
            }

            public boolean addStudent(Student student) {
                return false;
            }
        };
    }
}

4.2.3 修改提供服务的service熔断处理

公共service对某个service访问出现异常后统一处理的fallback处理

@FeignClient(value = “SPRINGCLOUD-PROVIDER-STUDENT”,fallbackFactory = StudentClientServiceFallbackFactory.class)

@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-STUDENT",fallbackFactory = StudentClientServiceFallbackFactory.class)
public interface StudentClientService {

    @GetMapping("/stu/get/{id}")
    public Student queryById(@PathVariable("id") Long id);

    @GetMapping("/stu/list")
    public List<Student> queryAll();

    @PostMapping("/stu/add")
    public boolean addStudent(Student student);
}

开启springcloud-consumer-dept-feign 的feign hystrix的降级

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

同时启动 注册中心springcloud-eureka-8801

服务提供者 springcloud-provider-student-8001

服务消费者springcloud-consumer-dept-feign

正常访问 http://localhost/consumer/stu/get/1

image-20201128144757362

关闭服务提供者springcloud-provider-student-8001

访问http://localhost/consumer/stu/get/1 服务降级

image-20201128144845642

5. Zuul路由网关

打开 C:\Windows\System32\drivers\etc\hosts 文件;

增加:127.0.0.1 myzuul.com

5.1 导入依赖

<dependencies>

        <!--Zuul-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--Hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!--实体类-->
        <dependency>
            <groupId>com.handc</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>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <!--eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

    </dependencies>

5.2 编写appliction.yml

server:
  port: 8888

spring:
  application:
    name: springcloud-zuul-gateway

# zuul注册到Eureka
eureka:
  client:
    service-url:
      defaultZone: http://eureka8801.com:8801/eureka/,http://eureka8802.com:8802/eureka/,http://eureka8803.com:8803/eureka/
  instance:
    instance-id: zuul8888
    prefer-ip-address: true


# info 配置
info:
  app.name: handc-springcloud
  company.name: blog.handc

#serviceId:映射的服务名;path:映射成为的路径;
#在yml修改之前使用:http://myzuul.com:8888/springcloud-provider-student/dept/get/2  访问;
#
#在yml修改之后使用:http://myzuul.com:8888/mystudent/dept/get/2  访问
zuul:
  routes:  
    mystudent.serviceId: springcloud-provider-student
    mystudent.path: /mystudent/**

  ignored-services: springcloud-provider-student  #不能再使用这个路径访问 只能使用自定义的路径访问

5.3 主启动类

添加@EnableZuulProxy

@SpringBootApplication
@EnableZuulProxy //开启服务
public class ZuulApplication_8888 {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication_8888.class, args);
    }
}

原路径已经不能访问 只能使用自定义路径

image-20201128153136730

使用自定义路由mystudent访问

image-20201128152835819

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值