# 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}