# suian-springcloud
**Repository Path**: cooljoker/suian-springcloud
## Basic Information
- **Project Name**: suian-springcloud
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-03-31
- **Last Updated**: 2025-04-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringCloud
### RestTemplate 与 Eureka
利用RestTemplate可以通过http连接进行调用,但是需要拼接url
String url = "http://127.0.0.1:1024/order/" + orderId;
Eureka管理了服务,帮忙管理了ip,port
url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/order/" + orderId;
### Eureka 高可用
```yaml
eureka:
client:
service-url:
# eureka服务地址;如果是集群则是其他服务器地址,后面要加/eureka
defaultZone: ${defaultZone:http://127.0.0.1:10086/eureka}
# register-with-eureka: false # 不向自身注册
# fetch-registry: false # 不拉取注册表
```
### Ribbon负载均衡
```java
@Bean
//负载均衡Ribbon
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
```
### hystrix 熔断器
hystrix熔断器现被遗弃
替代方案
| **实现库** | **优势** | **适用场景** |
|:---------------- |:------------------ |:------------- |
| **Resilience4j** | 轻量、功能全面、社区活跃 | 新项目首选,通用容错场景 |
| **Sentinel** | 动态规则配置、实时监控、流量控制精细 | 阿里生态、复杂流量控制需求 |
| **Spring Retry** | 简单易用、仅需重试机制 | 仅需重试功能的简单场景 |
#### Resilience4j
熔断降级
```java
@CircuitBreaker(name = "productServiceImpl", fallbackMethod = "fallbackGetProduct")
@Override
public ProductInfo selectProductById(Integer productId) {
// 模拟远程服务调用(可能失败)
if (Math.random() > 0.5) {
throw new RuntimeException("Service Error");
}
return productMapper.selectProductById(productId);
}
//降级方法
public ProductInfo fallbackGetProduct(Integer productId,Throwable ex) {
log.error("熔断器触发 productId: {}, Error: {}", productId, ex.getMessage());
// 返回默认值或缓存数据
return new ProductInfo();
}
```
## Feign远程调用
1、添加pom
```xml
org.springframework.cloud
spring-cloud-starter-openfeign
```
2、启动类添加注解@EnableFeignClients
```java
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //feign注解
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
```
3、写Feign客户端
```java
@FeignClient("order-service")
public interface OrderClient {
@GetMapping("/order/{orderId}")
OrderInfo getOrderById(@PathVariable("orderId") Integer orderId);
}
```
4、调用接口
```java
@Autowired
private OrderClient orderClient;
@CircuitBreaker(name = "productController",fallbackMethod = "fallback")
@RequestMapping("/order/{orderId}")
public OrderInfo getOrderById(@PathVariable("orderId") Integer orderId) {
return orderClient.getOrderById(orderId);
}
```
## Spring GateWay网关
1、引入pom(不要忘记引入eureka)
```xml
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
```
2、然后就是将自己注册到Eureka,以及写路由规则
如下面所示、就是所有服务都可以通过20000端口,以及对应的路由规则来进行,端口代理
```yml
server:
port: 20000
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
# 获取服务地址列表间隔时间,默认30秒
registry-fetch-interval-seconds: 10
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
# 路由id,随便写
- id: product-service
# 代理的服务地址
uri: lb://PRODUCT-SERVICE # 负载均衡到 USER-SERVICE
# uri: http://127.0.0.1:1025 # 负载均衡到 USER-SERVICE
predicates:
# - Path=/product/**
- Path=/api/product/**
filters:
# 表示过滤1个路径、2个路径,以此类推
- StripPrefix=1
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
```
### 局部过滤器
```java
@Component
public class WSGatewayFilterFactory extends AbstractGatewayFilterFactory {
private static final Logger logger = LoggerFactory.getLogger(WSGatewayFilterFactory.class);
public static final String PARAM_NAME = "param";
public WSGatewayFilterFactory() {
super(Config.class);
}
@Override
public List shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME);
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
if (request.getQueryParams().containsKey(config.param)) {
request.getQueryParams().get(config.param).forEach(
value -> logger.info("==============局部过滤器==============={}={}", config.param, value)
);
}
return chain.filter(exchange);
});
}
public static class Config {
private String param;
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
}
```
不要忘记在yml中设置,过滤器名字ws为XXGatewayFilterFactory中的XX
```yml
cloud:
gateway:
default-filters:
- AddResponseHeader=WS-NAME,SUIAN
routes:
# 路由id,随便写
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
#自定义过滤器
- WS=name
```
### 全局过滤器
使用场景:如token校验
```java
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
private static final Logger logger = LoggerFactory.getLogger(MyGlobalFilter.class);
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("==============全部过滤器MyGlobalFilter===============");
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isBlank(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
//值越小先行
return 1;
}
}
```
## 整合flowable
集成SpringBoot的Flowable会自动部署存储在process目录下的流程定义
当然也可以手动部署(bpmn放在其他的地方)
### 启动流程
{
查询流程实例
SELECT * FROM ACT_RE_PROCDEF WHERE KEY_ = 'rollbackDemo';
}
curl -X POST http://localhost:2010/process/start
### 根据流程实例查询流程id
curl -X POST http://localhost:2010/process/queryTask?processInstanceId={86720a78-193f-11f0-a95f-005056c00001}
### 完成任务(替换真实的taskId)
curl -X POST http://localhost:2010/process/complete?taskId={3dfe3845-193f-11f0-a95f-005056c00001}