springCloud 环境搭建 GuangZ
Eureka 注册服务搭建:
1:新建springBoot项目,版本选择2.0.4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2:在springAppliction启动类加入@EnableEurekaServer 注册,表示声明这是一个注册服务器。
配置appliction.yml文件
#声明该服务访问端口
server:
port: 1000
#声明该服务访问地址
eureka:
instance:
hostname: localhost
client:
#因为当前这个应用就是eureka服务器,没必要注册自身
registerWithEureka: false
#是否从eureka服务器获取注册信息
fetchRegistry: false
#查询服务和注册服务都需要依赖这个地址
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3:启动 springAppliction 访问 服务地址:端口号 。如下则说明注册成功
Eureka添加提供者服务
1:新建springBoot项目,添加依赖:
<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>
</dependency>
2:配置appliction.yml文件
#声明该服务名称(该服务被调用时会用到),注意名称不要有下划线。
spring:
application:
name: product-server
#声明该服务端口号
server:
port: 2000
#声明注册中心地址,用以将该服务交给注册中心管理
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1000/eureka/
3:编写业务逻辑:
Controller
@RestController
@RequestMapping("/product")
public class ProductCintroller {
//从配置文件中获取该服务端口号
@Value("${server.port}")
private String port;
@Autowired
private ProductService productService;
@RequestMapping("/list")
public Object list(){
return productService.list();
}
@RequestMapping("/find")
public Object find(@RequestParam("id")int id){
Product product = productService.find(id);
product.setName(product.getName()+"....................."+port);
return product;
}
}
Service
public interface ProductService {
public List<Product> list();
public Product find(int id);
}
ServiceImpl
@Service
public class ProductServiceImpl implements ProductService {
//声明一个List 用于时测试存储数据
private static final List<Product> list = new ArrayList<>();
//类加载时添加相应数据用于测试
static {
Product p1 = new Product(1,"苹果",100,500);
Product p2 = new Product(2,"香蕉",200,400);
Product p3 = new Product(3,"机子",300,300);
Product p4 = new Product(4,"等价物",400,200);
Product p5 = new Product(5,"例子",500,100);
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
list.add(p5);
}
@Override
public List<Product> list() {
return list;
}
@Override
public Product find(int id) {
return list.get(id);
}
}
4:启动springBootAppliction启动类,Eureka注册中心添加该服务
Eureka添加调用者 服务
1:新建SpringBoot项目,添加依赖
<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>
</dependency>
<!--feign服务调用 @FeignClient -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--hystrix 熔断器 主要用于 @HystrixCommand-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2:在springAppliction启动类加入
@EnableFeignClients 表示声明这是一个客户端服务器集成Ribbon(负载均衡)。
@EnableCircuitBreaker 表示加入服务熔断机制
配置appliction.yml文件、
#声明该服务名称
spring:
application:
name: order-server
#声明该服务端口
server:
port: 3000
#注册服务地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1000/eureka/
#开启 feign 自带的 hystrix,用于开启服务调用异常处理
feign:
hystrix:
enabled: true
3:当该服务需要调用提供者服务时添加相应服务的 service 接口 @FeignClient
//name:声明需要调用服务名称
//fallback:声明调用服务如果发生异常,处理的类。
@FeignClient(name = "product-server",fallback = ProductFallback.class)
public interface ProductService {
//该请求参数必须为所要调用服务Controller的url全路径。请求参数也要一样。
@RequestMapping("/product/find")
String find(@RequestParam("id") int id);
}
声明服务接口调用异常处理类:如果 ProductService 服务中的某个方法在被调用过程中发成异常会进入此类。 这里可以对错误做一个记入。
//将此类交给springBoot容器处理
@Component
//实现远程服务接口处理类。
public class ProductFallback implements ProductService {
//重写远程服务接口实现。
@Override
public String find(int id) {
System.out.println(" 在调用 ProductService 下的 find(int id)方法是发生了一个错误 ");
return null;
}
}
4:在服务最外层Controller明熔断处理。用以返回给调用者相关结果信息
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
//声明熔断处理方法,如果该处理方法执行过程发生异常则会进入fallbackMethod声明的方法。
@HystrixCommand(fallbackMethod = "orderFallBack")
@RequestMapping("/order")
public Object order(@RequestParam("id")int id,@RequestParam("productId")int productId){
Order order = orderService.save(id,productId);
Map<String,Object> map = new HashMap<>();
map.put("code","0");
map.put("msg",order);
return map;
}
//实现熔断处理方法
public Object orderFallBack(int id,int productId){
Map<String,Object> map = new HashMap<>();
map.put("code","-1");
map.put("msg","系统繁忙,稍后再试");
return map;
}
}
5:在调用方Controller层实现熔断报警机制(采用Redis,TimeUntil)
本地Redis启动:找到Redis安装目录 redis-server 命令
controller层调用服务方法上加 @HystrixCommand(fallbackMethod = "orderFallBack")//声明熔断处理方法
//Redis 注入
@Autowired
private StringRedisTemplate redisTemplate;
@HystrixCommand(fallbackMethod = "orderFallBack")//声明熔断处理方法
@RequestMapping("/order")
public Object order(@RequestParam("id")int id,@RequestParam("productId")int productId){
Order order = orderService.save(id,productId);
Map<String,Object> map = new HashMap<>();
map.put("code","0");
map.put("msg",order);
return map;
}
//实现熔断处理方法
public Object orderFallBack(int id,int productId){
//熔断之后 报警
String saveOrderKye = "save-order";
String sendValue = redisTemplate.opsForValue().get(saveOrderKye);
//为了效率 新开启一个线程
//此处采用java新特性lambda开启新线程
new Thread( ()->{
//查询缓存中是否有规定的变量如果没有则发消息。
if (StringUtils.isBlank(sendValue)){
System.out.println("紧急通知......用户下单失败.....请尽快处理");
//此处可以添加短信发送服务
//短信已经发送,为了避免一直重复发送,设置缓存中变量存在时间。
redisTemplate.opsForValue().set(saveOrderKye,"save-order", 20,TimeUnit.SECONDS);
}else {
System.out.println("已经提醒。时间未到");
}
}).start();
Map<String,Object> map = new HashMap<>();
map.put("code","-1");
map.put("msg","系统繁忙,稍后再试");
return map;
}
appliction.yml文件中添加 hystrix 熔断降级机制
#因为hystrix内部有熔断降级机制,有时候网络延迟的情况下就算被调用的服务正常
#hystrix也会执行熔断。
hystrix:
command:
default:
execution:
#把hystrix超时关闭:不建议
#timeout:
#enabled: false
#设置超时时间为4秒 默认为1秒
isolation:
thread:
timeoutInMilliseconds: 4000
6、断路器Dashboard监控仪表盘
SpringBootAppliction启动类添加注解 @EnableHystrixDashboard
添加Dashboard监控仪表盘依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
appliction.yml文件添加仪表盘配置
#配置监控仪表盘
#暴露全部监控信息
management:
endpoints:
web:
exposure:
include: "*"
访问入口 http://localhost:8781/hystrixHystrix
Dashboard输入: http://localhost:8781/actuator/hystrix.stream
参考资料 默认开启监控配置