微服务条目 | 技术 |
---|---|
服务开发 | SpringBoot, Sprin,g SpringMVC |
服务注册与发现 | Eureka, Consul, Zookerrper |
服务调用 | Rest, RPC, gRPC |
服务熔断器 | Hystrix, Envoy |
负载均衡 | Ribbon, Nginx |
服务器接口调用 | Feign |
消息队列 | Kafka, RabbitMQ, ActiveMQ |
服务配置中心管理 | SpringCloudConfig |
服务路由(API网关) | Zuul |
依赖版本
依赖 | 版本 |
---|---|
SpringCloud | Hoxton.SR8 |
SpringBoot | 2.3.3.RELEASE |
spring-cloud-starter-netflix-eureka-client | 2.2.5.RELEASE |
spring-cloud-starter-netflix-eureka-server | 2.2.5.RELEASE |
spring-cloud-starter-netflix-ribbon | 2.2.5.RELEASE |
spring-cloud-starter-openfeign | 2.2.5.RELEASE |
spring-cloud-starter-netflix-hystrix | 2.2.5.RELEASE |
spring-cloud-starter-netflix-hystrix-dashboard | 2.2.5.RELEASE |
spring-cloud-starter-netflix-zuul | 2.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
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 测试
同时启动三个注册中心 和三个服务提供者
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负载均衡到不同服务提供者
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
访问 http://localhost/consumer/stu/get/20 出现服务熔断
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
关闭服务提供者springcloud-provider-student-8001
访问http://localhost/consumer/stu/get/1 服务降级
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);
}
}
原路径已经不能访问 只能使用自定义路径
使用自定义路由mystudent访问