From 2a79fca22c5462e32ea55ba846ca201ede455fb4 Mon Sep 17 00:00:00 2001 From: JACKYMYPERSON <1627832236@qq.com> Date: Tue, 3 Mar 2026 13:14:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=AD=A6=E4=B9=A0=E4=BA=8B?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javamemories-gateway/pom.xml | 11 ++++ .../Config/SentinelDegradeConfig.java | 40 ++++++++++++++ .../src/main/resources/application.yml | 17 +++++- order-service/pom.xml | 36 +++++++++++++ .../src/main/java/cn/mayiming/App.java | 2 + .../mayiming/Controller/OrderController.java | 16 ++++-- .../java/cn/mayiming/Mapper/OrderMapper.java | 33 ++++++++++++ .../cn/mayiming/Service/OrderService.java | 17 ++++++ .../main/java/cn/mayiming/entity/Order.java | 54 +++++++++++++++++++ .../cn/mayiming/feign/UserFeignClient.java | 6 +++ .../src/main/resources/application.yml | 22 +++++++- .../src/main/java/cn/mayiming/App.java | 2 +- .../src/main/java/cn/mayiming/App.java | 2 + .../mayiming/Controller/UserController.java | 18 +++++-- .../java/cn/mayiming/Mapper/UserMapper.java | 16 ++++-- .../java/cn/mayiming/Service/UserService.java | 15 ++++++ .../main/java/cn/mayiming/entity/User.java | 20 +++++++ 17 files changed, 310 insertions(+), 17 deletions(-) create mode 100644 javamemories-gateway/src/main/java/cn/mayiming/Config/SentinelDegradeConfig.java create mode 100644 order-service/src/main/java/cn/mayiming/Mapper/OrderMapper.java create mode 100644 order-service/src/main/java/cn/mayiming/entity/Order.java diff --git a/javamemories-gateway/pom.xml b/javamemories-gateway/pom.xml index 725d67c..5c588c8 100644 --- a/javamemories-gateway/pom.xml +++ b/javamemories-gateway/pom.xml @@ -43,5 +43,16 @@ redis.clients jedis + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + diff --git a/javamemories-gateway/src/main/java/cn/mayiming/Config/SentinelDegradeConfig.java b/javamemories-gateway/src/main/java/cn/mayiming/Config/SentinelDegradeConfig.java new file mode 100644 index 0000000..132fcbd --- /dev/null +++ b/javamemories-gateway/src/main/java/cn/mayiming/Config/SentinelDegradeConfig.java @@ -0,0 +1,40 @@ +package cn.mayiming.Config; + +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; +import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy; +import jakarta.annotation.PostConstruct; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; + +/** + * Sentinel 熔断规则配置 + * 为下游服务配置熔断策略 + */ +@Configuration +public class SentinelDegradeConfig { + + /** + * 初始化熔断规则 + * @PostConstruct:Spring 容器启动后执行 + */ + @PostConstruct + public void initDegradeRules() { + List rules = new ArrayList<>(); + + DegradeRule orderServiceRule = new DegradeRule(); + orderServiceRule.setResource("order-service"); // 网关路由ID/服务名 + // 关键:改为慢请求比例触发熔断 + + orderServiceRule.setCount(3000); // 慢请求阈值:3000毫秒(3秒),超过3秒即为慢请求 + orderServiceRule.setSlowRatioThreshold(0.5); // 慢请求比例阈值:50%(超过50%的请求是慢请求则触发熔断) + orderServiceRule.setTimeWindow(10); // 熔断后保持打开状态10秒 + orderServiceRule.setMinRequestAmount(5); // 最小请求数:累计5次请求后才计算慢请求比例 + + rules.add(orderServiceRule); + DegradeRuleManager.loadRules(rules); + } +} \ No newline at end of file diff --git a/javamemories-gateway/src/main/resources/application.yml b/javamemories-gateway/src/main/resources/application.yml index 4f03ffe..19ffbfa 100644 --- a/javamemories-gateway/src/main/resources/application.yml +++ b/javamemories-gateway/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8080 + port: 8081 spring: application: @@ -44,6 +44,21 @@ spring: # 按 IP 限流(默认) key-resolver: "#{@ipKeyResolver}" + sentinel: + # Sentinel 控制台地址(如果启动了控制台,用于可视化配置) + transport: + dashboard: localhost:8080 # Sentinel 控制台端口,默认8080 + port: 8719 # 客户端和控制台通信的端口 + # 网关熔断配置 + gateway: + enabled: true # 开启 Sentinel 网关适配 + # 熔断后默认的降级响应 + fallback: + mode: response # 降级方式:返回自定义响应 + response-status: 503 # 降级响应状态码 + response-body: "{\"code\":503,\"msg\":\"服务暂时不可用,请稍后重试\",\"data\":null}" # 降级响应体 + response-content-type: application/json + # Nacos 注册 nacos: discovery: diff --git a/order-service/pom.xml b/order-service/pom.xml index c5781d3..b2fecf4 100644 --- a/order-service/pom.xml +++ b/order-service/pom.xml @@ -42,5 +42,41 @@ org.springframework.cloud spring-cloud-starter-loadbalancer + + com.alibaba.csp + sentinel-core + + + org.projectlombok + lombok + provided + + + org.mybatis + mybatis + 3.5.19 + compile + + + org.mybatis + mybatis-spring + 4.0.0 + compile + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + + + com.mysql + mysql-connector-j + runtime + diff --git a/order-service/src/main/java/cn/mayiming/App.java b/order-service/src/main/java/cn/mayiming/App.java index a24ce16..33ce62e 100644 --- a/order-service/src/main/java/cn/mayiming/App.java +++ b/order-service/src/main/java/cn/mayiming/App.java @@ -1,5 +1,6 @@ package cn.mayiming; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @@ -10,6 +11,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; */ @SpringBootApplication @EnableFeignClients +@MapperScan("cn.mayiming.Mapper") public class App { public static void main( String[] args ) diff --git a/order-service/src/main/java/cn/mayiming/Controller/OrderController.java b/order-service/src/main/java/cn/mayiming/Controller/OrderController.java index 92ff990..efbab80 100644 --- a/order-service/src/main/java/cn/mayiming/Controller/OrderController.java +++ b/order-service/src/main/java/cn/mayiming/Controller/OrderController.java @@ -2,11 +2,13 @@ package cn.mayiming.Controller; import cn.mayiming.Service.OrderService; +import cn.mayiming.entity.Order; import cn.mayiming.entity.User; +import com.alibaba.csp.sentinel.annotation.SentinelResource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController public class OrderController { @@ -15,7 +17,13 @@ public class OrderController { private OrderService orderService; @PostMapping("/order") - public User getOrder(@RequestBody User user){ + public User getUserOrder(@RequestBody User user){ + //throw new RuntimeException("Cuowu "); return orderService.SearchUserbyname(user); } + + @GetMapping("/order") + public List getUserOrder(@RequestParam Integer id){ + return orderService.OrderListById(id); + } } diff --git a/order-service/src/main/java/cn/mayiming/Mapper/OrderMapper.java b/order-service/src/main/java/cn/mayiming/Mapper/OrderMapper.java new file mode 100644 index 0000000..6b4c741 --- /dev/null +++ b/order-service/src/main/java/cn/mayiming/Mapper/OrderMapper.java @@ -0,0 +1,33 @@ +package cn.mayiming.Mapper; + + +import cn.mayiming.entity.Order; +import feign.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface OrderMapper { + + /** + * 根据用户ID查询所有订单 + * @param userId 用户ID(@Param 注解解决参数名绑定问题) + * @return 该用户的所有订单列表(按创建时间倒序) + */ + @Select("SELECT id, " + + "order_no AS orderNo, " + + "user_id AS userId, " + + "product_name AS productName, " + + "product_price AS productPrice, " + + "count, " + + "total_amount AS totalAmount, " + + "status, " + + "create_time AS createTime, " + + "update_time AS updateTime " + + "FROM t_order " + + "WHERE user_id = #{userId} " + + "ORDER BY create_time DESC") + List selectByUserId(@Param("userId") Integer userId); +} diff --git a/order-service/src/main/java/cn/mayiming/Service/OrderService.java b/order-service/src/main/java/cn/mayiming/Service/OrderService.java index b9ef406..daddd6b 100644 --- a/order-service/src/main/java/cn/mayiming/Service/OrderService.java +++ b/order-service/src/main/java/cn/mayiming/Service/OrderService.java @@ -1,17 +1,34 @@ package cn.mayiming.Service; +import cn.mayiming.Mapper.OrderMapper; +import cn.mayiming.entity.Order; import cn.mayiming.entity.User; import cn.mayiming.feign.UserFeignClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + @Service public class OrderService { @Autowired private UserFeignClient userFeignClient; + @Autowired + private OrderMapper orderMapper; + public User SearchUserbyname (User user) { return userFeignClient.selectByUsername(user); } + public List OrderListById(Integer id) { + User user = userFeignClient.GetUserByid(id); + + if(user == null) { + throw new RuntimeException("错误!"); + } + return orderMapper.selectByUserId(id); + + } + } diff --git a/order-service/src/main/java/cn/mayiming/entity/Order.java b/order-service/src/main/java/cn/mayiming/entity/Order.java new file mode 100644 index 0000000..c484096 --- /dev/null +++ b/order-service/src/main/java/cn/mayiming/entity/Order.java @@ -0,0 +1,54 @@ +package cn.mayiming.entity; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data // Lombok 注解,自动生成get/set/toString +public class Order { + /** 订单ID */ + private Long id; + /** 订单编号 */ + private String orderNo; + /** 关联用户ID */ + private Integer userId; + /** 商品名称 */ + private String productName; + /** 商品单价 */ + private BigDecimal productPrice; + /** 购买数量 */ + private Integer count; + /** 订单总金额 */ + private BigDecimal totalAmount; + /** 订单状态:0-待支付 1-已支付 2-已取消 3-已完成 */ + private Integer status; + /** 创建时间 */ + private Date createTime; + /** 更新时间 */ + private Date updateTime; + + // 可选:添加状态枚举,避免硬编码数字 + public enum OrderStatus { + PENDING_PAYMENT(0, "待支付"), + PAID(1, "已支付"), + CANCELLED(2, "已取消"), + COMPLETED(3, "已完成"); + + private final int code; + private final String desc; + + OrderStatus(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } + } +} \ No newline at end of file diff --git a/order-service/src/main/java/cn/mayiming/feign/UserFeignClient.java b/order-service/src/main/java/cn/mayiming/feign/UserFeignClient.java index 5ee2147..8de9b78 100644 --- a/order-service/src/main/java/cn/mayiming/feign/UserFeignClient.java +++ b/order-service/src/main/java/cn/mayiming/feign/UserFeignClient.java @@ -3,10 +3,16 @@ package cn.mayiming.feign; import cn.mayiming.entity.User; import feign.Param; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "user-service") public interface UserFeignClient { @PostMapping("/user") User selectByUsername(User user); + + @GetMapping("/user") + User GetUserByid(@RequestParam("id") Integer id); + } diff --git a/order-service/src/main/resources/application.yml b/order-service/src/main/resources/application.yml index a9021ac..34fe535 100644 --- a/order-service/src/main/resources/application.yml +++ b/order-service/src/main/resources/application.yml @@ -18,4 +18,24 @@ spring: namespace: public group: DEFAULT_GROUP config: - import: nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}?server-addr=${spring.cloud.nacos.config.server-addr} \ No newline at end of file + import: nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}?server-addr=${spring.cloud.nacos.config.server-addr} + + datasource: + # 数据库驱动类(MySQL 8.x 用 com.mysql.cj.jdbc.Driver,5.x 用 com.mysql.jdbc.Driver) + driver-class-name: com.mysql.cj.jdbc.Driver + # 数据库连接 URL(替换为你的数据库地址、端口、库名,如 user_db) + url: jdbc:mysql://rm-f8z6oc5a03331500p8o.mysql.rds.aliyuncs.com:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + # 数据库用户名(默认 root,根据实际情况修改) + username: root + # 数据库密码(替换为你的 MySQL 密码) + password: Root123456 + # 可选:连接池配置(推荐使用 HikariCP,Spring Boot 2.x 默认) + hikari: + # 连接池最大连接数 + maximum-pool-size: 10 + # 连接池最小空闲连接数 + minimum-idle: 2 + # 连接超时时间(毫秒) + connection-timeout: 30000 + # 连接最大存活时间(毫秒) + max-lifetime: 1800000 \ No newline at end of file diff --git a/request-test/src/main/java/cn/mayiming/App.java b/request-test/src/main/java/cn/mayiming/App.java index 083c6ac..ea2ecbe 100644 --- a/request-test/src/main/java/cn/mayiming/App.java +++ b/request-test/src/main/java/cn/mayiming/App.java @@ -20,7 +20,7 @@ public class App // 请求体JSON数据 private static final String REQUEST_BODY = "{\"username\":\"admin\"}"; // 总请求次数 - private static final int TOTAL_REQUESTS = 30; + private static final int TOTAL_REQUESTS = 50; public static void main(String[] args) { // 1. 创建HttpClient实例(设置超时时间10秒) diff --git a/user-service/src/main/java/cn/mayiming/App.java b/user-service/src/main/java/cn/mayiming/App.java index 48c58d1..69e4587 100644 --- a/user-service/src/main/java/cn/mayiming/App.java +++ b/user-service/src/main/java/cn/mayiming/App.java @@ -4,6 +4,7 @@ package cn.mayiming; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; /** * Hello world! @@ -12,6 +13,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("cn.mayiming.Mapper") +@EnableTransactionManagement public class App { public static void main( String[] args ) diff --git a/user-service/src/main/java/cn/mayiming/Controller/UserController.java b/user-service/src/main/java/cn/mayiming/Controller/UserController.java index a53b05c..ab59dfa 100644 --- a/user-service/src/main/java/cn/mayiming/Controller/UserController.java +++ b/user-service/src/main/java/cn/mayiming/Controller/UserController.java @@ -4,18 +4,26 @@ import cn.mayiming.Mapper.UserMapper; import cn.mayiming.Service.UserService; import cn.mayiming.entity.User; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController public class UserController { @Autowired - private UserMapper userMapper; + private UserService userService; @PostMapping("/user") public User getUser(@RequestBody User user) { - return userMapper.selectByUsername(user.getUsername()); + return userService.getUserByUsername(user.getUsername()); + } + + @PutMapping("/user") + public int updateUser(@RequestBody User user) { + return userService.updateUser(user); + } + + @GetMapping("/user") + public User GetUserByid(@RequestParam Integer id) { + return userService.getUserById(id); } } diff --git a/user-service/src/main/java/cn/mayiming/Mapper/UserMapper.java b/user-service/src/main/java/cn/mayiming/Mapper/UserMapper.java index 65232fa..f3defe0 100644 --- a/user-service/src/main/java/cn/mayiming/Mapper/UserMapper.java +++ b/user-service/src/main/java/cn/mayiming/Mapper/UserMapper.java @@ -40,11 +40,17 @@ public interface UserMapper { * @param user 用户对象(含要更新的字段) * @return 影响行数 */ - @Update("UPDATE user SET " + - "username = #{username}, " + - "password = #{password}, " + - "nickname = #{nickname} " + - "WHERE id = #{id}") + @Update({ + "" + }) int updateById(User user); /** diff --git a/user-service/src/main/java/cn/mayiming/Service/UserService.java b/user-service/src/main/java/cn/mayiming/Service/UserService.java index 5f64e49..4b58af7 100644 --- a/user-service/src/main/java/cn/mayiming/Service/UserService.java +++ b/user-service/src/main/java/cn/mayiming/Service/UserService.java @@ -2,8 +2,10 @@ package cn.mayiming.Service; import cn.mayiming.Mapper.UserMapper; import cn.mayiming.entity.User; +import org.apache.ibatis.jdbc.Null; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -21,6 +23,7 @@ public class UserService { return rows; } + // 根据用户名查询 public User getUserByUsername(String username) { return userMapper.selectByUsername(username); @@ -30,4 +33,16 @@ public class UserService { public List getAllUsers() { return userMapper.selectAll(); } + + public User getUserById(Integer id) { + return userMapper.selectById(id); + } + + @Transactional(rollbackFor = Exception.class) + public int updateUser(User user) { + if (user.getId() == null){ + throw new IllegalArgumentException("更新失败:用户ID不能为空"); + } + return userMapper.updateById(user); + } } diff --git a/user-service/src/main/java/cn/mayiming/entity/User.java b/user-service/src/main/java/cn/mayiming/entity/User.java index 3618d51..48dd67c 100644 --- a/user-service/src/main/java/cn/mayiming/entity/User.java +++ b/user-service/src/main/java/cn/mayiming/entity/User.java @@ -19,4 +19,24 @@ public class User { String username; String password; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + Integer id; + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + String nickname; }