当前位置: 首页 > news >正文

【!!!!终极 Java 中间件实战课:从 0 到 1 构建亿级流量电商系统全链路解决方案!!!!保姆级教程---超细】

终极 Java 中间件实战课:电商系统架构实战教程

  • 电商系统架构实战教程
    • 1. 系统架构设计
      • 1.1 系统模块划分
      • 1.2 技术选型
    • 2. 环境搭建
      • 2.1 开发环境准备
      • 2.2 基础设施部署
    • 3. 用户服务开发
      • 3.1 创建Maven项目
      • 3.2 创建用户服务模块
      • 3.3 配置文件
      • 3.4 实体类与数据库设计
      • 3.5 DAO层实现
      • 3.6 Service层实现
      • 3.7 Controller层实现
      • 3.8 主应用类
    • 4. 商品服务开发
    • 5. 订单服务开发
    • 6. 网关服务开发
    • 7. 服务调用与集成
    • 8. 分布式事务处理
    • 9. 服务监控与熔断
    • 10. 日志收集与分析平台
    • 11. 系统部署与性能优化
    • 12. 高级主题实现
    • 总结

电商系统架构实战教程

1. 系统架构设计

1.1 系统模块划分

电商系统通常包含以下核心模块:

  • 用户服务:用户注册、登录、信息管理
  • 商品服务:商品管理、库存管理
  • 订单服务:订单创建、支付、物流
  • 营销服务:优惠券、促销活动
  • 支付服务:对接第三方支付
  • 网关服务:统一入口、权限校验
  • 后台管理:运营管理界面

1.2 技术选型

  • 开发语言:Java 11+
  • 框架:Spring Boot 2.7+、Spring Cloud
  • 注册中心:Nacos
  • 配置中心:Nacos
  • 网关:Spring Cloud Gateway
  • 服务调用:OpenFeign
  • 负载均衡:Ribbon
  • 熔断限流:Sentinel
  • 消息队列:RocketMQ
  • 缓存:Redis
  • 数据库:MySQL
  • 搜索引擎:Elasticsearch
  • 分布式事务:Seata

2. 环境搭建

2.1 开发环境准备

  1. 安装JDK 11+
  2. 安装Maven 3.6+
  3. 安装IntelliJ IDEA
  4. 安装DockerDocker Compose

2.2 基础设施部署

使用Docker Compose部署基础中间件:

version: '3'
services:# Nacos服务注册与配置中心nacos:image: nacos/nacos-server:2.0.3container_name: nacosenvironment:MODE: standaloneports:- "8848:8848"- "9848:9848"- "9849:9849"volumes:- ./nacos/logs:/home/nacos/logs- ./nacos/init.d:/home/nacos/init.d# Redis缓存redis:image: redis:6.2.6container_name: redisports:- "6379:6379"volumes:- ./redis/data:/datacommand: redis-server --appendonly yes# MySQL数据库mysql:image: mysql:8.0.26container_name: mysqlenvironment:MYSQL_ROOT_PASSWORD: rootMYSQL_DATABASE: ecom_dbports:- "3306:3306"volumes:- ./mysql/data:/var/lib/mysql- ./mysql/init:/docker-entrypoint-initdb.d# RocketMQ消息队列rocketmq:image: rocketmqinc/rocketmq:4.9.2container_name: rocketmqports:- "9876:9876"- "10909:10909"- "10911:10911"command: sh mqnamesrv && sh mqbroker -n localhost:9876# Elasticsearch搜索引擎elasticsearch:image: elasticsearch:7.17.3container_name: elasticsearchenvironment:- discovery.type=single-node- ES_JAVA_OPTS=-Xms512m -Xmx512mports:- "9200:9200"- "9300:9300"volumes:- ./elasticsearch/data:/usr/share/elasticsearch/data# Kibana可视化工具kibana:image: kibana:7.17.3container_name: kibanaports:- "5601:5601"depends_on:- elasticsearch

3. 用户服务开发

3.1 创建Maven项目

首先创建一个基础的Maven项目作为父工程:

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ecommerce</groupId><artifactId>ecommerce-parent</artifactId><version>1.0.0</version><packaging>pom</packaging><modules><module>user-service</module><module>product-service</module><module>order-service</module><module>gateway-service</module></modules><properties><java.version>11</java.version><spring-boot.version>2.7.10</spring-boot.version><spring-cloud.version>2021.0.5</spring-cloud.version></properties><dependencyManagement><dependencies><!-- Spring Boot依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!-- Spring Cloud依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- MyBatis依赖 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><!-- Nacos依赖 --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>2.0.3</version></dependency></dependencies></dependencyManagement>
</project>

3.2 创建用户服务模块

<!-- user-service/pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.ecommerce</groupId><artifactId>ecommerce-parent</artifactId><version>1.0.0</version></parent><artifactId>user-service</artifactId><dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Data JPA --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- Nacos Discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- Sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies>
</project>

3.3 配置文件

# user-service/src/main/resources/application.yml
spring:application:name: user-service  # 服务名称cloud:nacos:discovery:server-addr: localhost:8848  # Nacos服务地址datasource:url: jdbc:mysql://localhost:3306/ecom_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverredis:host: localhostport: 6379server:port: 8081  # 服务端口mybatis:mapper-locations: classpath:mapper/*.xml  # MyBatis映射文件位置type-aliases-package: com.ecommerce.user.entity  # 实体类包路径

3.4 实体类与数据库设计

// user-service/src/main/java/com/ecommerce/user/entity/User.java
package com.ecommerce.user.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;/*** 用户实体类*/
@Data
@Entity
@Table(name = "t_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;  // 用户ID@Column(nullable = false, unique = true)private String username;  // 用户名@Column(nullable = false)private String password;  // 密码(加密存储)@Column(nullable = false)private String phone;  // 手机号private String email;  // 邮箱private Integer status;  // 用户状态:0-禁用,1-正常@Temporal(TemporalType.TIMESTAMP)@Column(nullable = false)private Date createTime;  // 创建时间@Temporal(TemporalType.TIMESTAMP)@Column(nullable = false)private Date updateTime;  // 更新时间
}

3.5 DAO层实现

// user-service/src/main/java/com/ecommerce/user/dao/UserDao.java
package com.ecommerce.user.dao;import com.ecommerce.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;/*** 用户DAO接口*/
public interface UserDao extends JpaRepository<User, Long> {/*** 根据用户名查找用户* @param username 用户名* @return 用户实体*/User findByUsername(String username);/*** 根据手机号查找用户* @param phone 手机号* @return 用户实体*/User findByPhone(String phone);
}

3.6 Service层实现

// user-service/src/main/java/com/ecommerce/user/service/UserService.java
package com.ecommerce.user.service;import com.ecommerce.user.entity.User;
import com.ecommerce.user.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.Date;
import java.util.Optional;/*** 用户服务实现*/
@Service
public class UserService {@Autowiredprivate UserDao userDao;/*** 用户注册* @param user 用户信息* @return 注册结果*/@Transactionalpublic User register(User user) {// 检查用户名是否已存在User existUser = userDao.findByUsername(user.getUsername());if (existUser != null) {throw new RuntimeException("用户名已存在");}// 检查手机号是否已存在existUser = userDao.findByPhone(user.getPhone());if (existUser != null) {throw new RuntimeException("手机号已注册");}// 设置默认值user.setStatus(1);  // 默认启用user.setCreateTime(new Date());user.setUpdateTime(new Date());// 密码加密(实际项目中应该使用加密算法)user.setPassword("{noop}" + user.getPassword());// 保存用户信息return userDao.save(user);}/*** 用户登录* @param username 用户名* @param password 密码* @return 用户信息*/public User login(String username, String password) {User user = userDao.findByUsername(username);if (user == null) {throw new RuntimeException("用户不存在");}// 验证密码(实际项目中应该使用加密比较)if (!user.getPassword().equals("{noop}" + password)) {throw new RuntimeException("密码错误");}return user;}/*** 根据ID获取用户信息* @param id 用户ID* @return 用户信息*/public User getById(Long id) {Optional<User> userOptional = userDao.findById(id);return userOptional.orElse(null);}
}

3.7 Controller层实现

// user-service/src/main/java/com/ecommerce/user/controller/UserController.java
package com.ecommerce.user.controller;import com.ecommerce.user.entity.User;
import com.ecommerce.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.HashMap;
import java.util.Map;/*** 用户控制器*/
@RestController
@RequestMapping("/api/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册接口* @param user 用户信息* @return 注册结果*/@PostMapping("/register")public Map<String, Object> register(@RequestBody User user) {Map<String, Object> result = new HashMap<>();try {User newUser = userService.register(user);result.put("success", true);result.put("message", "注册成功");result.put("data", newUser);} catch (Exception e) {result.put("success", false);result.put("message", e.getMessage());}return result;}/*** 用户登录接口* @param username 用户名* @param password 密码* @return 登录结果*/@PostMapping("/login")public Map<String, Object> login(@RequestParam String username, @RequestParam String password) {Map<String, Object> result = new HashMap<>();try {User user = userService.login(username, password);result.put("success", true);result.put("message", "登录成功");result.put("data", user);// 实际项目中这里应该生成Token返回给客户端// String token = jwtService.generateToken(user);// result.put("token", token);} catch (Exception e) {result.put("success", false);result.put("message", e.getMessage());}return result;}/*** 获取用户信息接口* @param id 用户ID* @return 用户信息*/@GetMapping("/{id}")public Map<String, Object> getById(@PathVariable Long id) {Map<String, Object> result = new HashMap<>();try {User user = userService.getById(id);if (user != null) {result.put("success", true);result.put("data", user);} else {result.put("success", false);result.put("message", "用户不存在");}} catch (Exception e) {result.put("success", false);result.put("message", e.getMessage());}return result;}
}

3.8 主应用类

// user-service/src/main/java/com/ecommerce/user/UserServiceApplication.java
package com.ecommerce.user;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/*** 用户服务启动类*/
@SpringBootApplication
@EnableDiscoveryClient  // 启用服务发现
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}

4. 商品服务开发

商品服务负责管理商品信息和库存,下面是核心代码实现:

// product-service/src/main/java/com/ecommerce/product/entity/Product.java
package com.ecommerce.product.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;/*** 商品实体类*/
@Data
@Entity
@Table(name = "t_product")
public class Product implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;  // 商品ID@Column(nullable = false)private String name;  // 商品名称@Column(nullable = false)private String description;  // 商品描述@Column(nullable = false)private BigDecimal price;  // 商品价格@Column(nullable = false)private Integer stock;  // 库存数量@Column(nullable = false)private Integer status;  // 商品状态:0-下架,1-上架@Column(nullable = false)private String imageUrl;  // 商品图片URL@Temporal(TemporalType.TIMESTAMP)@Column(nullable = false)private Date createTime;  // 创建时间@Temporal(TemporalType.TIMESTAMP)@Column(nullable = false)private Date updateTime;  // 更新时间
}
// product-service/src/main/java/com/ecommerce/product/service/ProductService.java
package com.ecommerce.product.service;import com.ecommerce.product.entity.Product;
import com.ecommerce.product.dao.ProductDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;/*** 商品服务实现*/
@Service
public class ProductService {@Autowiredprivate ProductDao productDao;@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 获取商品列表* @return 商品列表*/public List<Product> listProducts() {// 优先从缓存获取String key = "product:list";List<Product> productList = (List<Product>) redisTemplate.opsForValue().get(key);if (productList == null) {// 缓存未命中,从数据库获取productList = productDao.findAll();// 放入缓存,设置过期时间10分钟redisTemplate.opsForValue().set(key, productList, 10, TimeUnit.MINUTES);}return productList;}/*** 根据ID获取商品* @param id 商品ID* @return 商品信息*/public Product getProductById(Long id) {// 优先从缓存获取String key = "product:" + id;Product product = (Product) redisTemplate.opsForValue().get(key);if (product == null) {// 缓存未命中,从数据库获取Optional<Product> productOptional = productDao.findById(id);if (productOptional.isPresent()) {product = productOptional.get();// 放入缓存,设置过期时间5分钟redisTemplate.opsForValue().set(key, product, 5, TimeUnit.MINUTES);}}return product;}/*** 扣减库存* @param productId 商品ID* @param quantity 扣减数量* @return 扣减结果*/@Transactionalpublic boolean reduceStock(Long productId, Integer quantity) {// 检查库存Product product = getProductById(productId);if (product == null || product.getStock() < quantity) {return false;}// 扣减库存int rows = productDao.reduceStock(productId, quantity);if (rows > 0) {// 库存更新成功,清除缓存redisTemplate.delete("product:" + productId);redisTemplate.delete("product:list");return true;}return false;}
}

5. 订单服务开发

订单服务负责订单的创建、支付和物流跟踪,下面是核心代码:

// order-service/src/main/java/com/ecommerce/order/entity/Order.java
package com.ecommerce.order.entity;import lombok.Data;import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;/*** 订单实体类*/
@Data
@Entity
@Table(name = "t_order")
public class Order implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;  // 订单ID@Column(nullable = false, unique = true)private String orderNo;  // 订单编号@Column(nullable = false)private Long userId;  // 用户ID@Column(nullable = false)private BigDecimal totalAmount;  // 订单总金额@Column(nullable = false)private Integer status;  // 订单状态:0-待支付,1-已支付,2-已发货,3-已完成,4-已取消@Column(nullable = false)private String receiverName;  // 收货人姓名@Column(nullable = false)private String receiverPhone;  // 收货人电话@Column(nullable = false)private String receiverAddress;  // 收货地址@Temporal(TemporalType.TIMESTAMP)@Column(nullable = false)private Date createTime;  // 创建时间@Temporal(TemporalType.TIMESTAMP)private Date payTime;  // 支付时间@Temporal(TemporalType.TIMESTAMP)private Date deliveryTime;  // 发货时间@Temporal(TemporalType.TIMESTAMP)private Date completeTime;  // 完成时间@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)private List<OrderItem> orderItems;  // 订单商品项
}
// order-service/src/main/java/com/ecommerce/order/service/OrderService.java
package com.ecommerce.order.service;import com.ecommerce.order.entity.Order;
import com.ecommerce.order.entity.OrderItem;
import com.ecommerce.order.dao.OrderDao;
import com.ecommerce.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;/*** 订单服务实现*/
@Service
public class OrderService {@Autowiredprivate OrderDao orderDao;@Autowiredprivate ProductService productService;/*** 创建订单* @param userId 用户ID* @param orderItems 订单商品项* @param receiverName 收货人姓名* @param receiverPhone 收货人电话* @param receiverAddress 收货地址* @return 订单ID*/@Transactionalpublic Long createOrder(Long userId, List<OrderItem> orderItems, String receiverName, String receiverPhone, String receiverAddress) {// 计算订单总金额BigDecimal totalAmount = BigDecimal.ZERO;for (OrderItem item : orderItems) {// 检查库存并扣减boolean success = productService.reduceStock(item.getProductId(), item.getQuantity());if (!success) {throw new RuntimeException("商品库存不足");}// 计算商品小计BigDecimal itemAmount = item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()));item.setAmount(itemAmount);totalAmount = totalAmount.add(itemAmount);}// 创建订单Order order = new Order();order.setOrderNo(generateOrderNo());order.setUserId(userId);order.setTotalAmount(totalAmount);order.setStatus(0);  // 待支付order.setReceiverName(receiverName);order.setReceiverPhone(receiverPhone);order.setReceiverAddress(receiverAddress);order.setCreateTime(new Date());order.setOrderItems(orderItems);// 设置订单关联for (OrderItem item : orderItems) {item.setOrder(order);}// 保存订单orderDao.save(order);return order.getId();}/*** 支付订单* @param orderId 订单ID* @return 支付结果*/@Transactionalpublic boolean payOrder(Long orderId) {Order order = orderDao.findById(orderId).orElse(null);if (order == null) {throw new RuntimeException("订单不存在");}if (order.getStatus() != 0) {throw new RuntimeException("订单状态不正确,不能支付");}// 更新订单状态为已支付order.setStatus(1);order.setPayTime(new Date());orderDao.save(order);// 发送支付成功消息(使用RocketMQ)// messageService.sendOrderPaidMessage(order);return true;}/*** 生成订单编号* @return 订单编号*/private String generateOrderNo() {// 实际项目中应该使用更严谨的订单号生成策略return "ORD" + UUID.randomUUID().toString().replace("-", "").substring(0, 15);}
}

6. 网关服务开发

网关服务作为系统统一入口,负责路由、权限校验和限流等功能:

// gateway-service/src/main/java/com/ecommerce/gateway/GatewayApplication.java
package com.ecommerce.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;/*** 网关服务启动类*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}/*** 跨域配置*/@Beanpublic CorsWebFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedMethod("*");config.addAllowedOriginPattern("*");config.addAllowedHeader("*");config.setAllowCredentials(true);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}
# gateway-service/src/main/resources/application.yml
spring:application:name: gateway-servicecloud:nacos:discovery:server-addr: localhost:8848gateway:routes:- id: user-serviceuri: lb://user-service  # 负载均衡到user-servicepredicates:- Path=/api/user/**filters:- StripPrefix=2  # 去除路径前缀/api/user- id: product-serviceuri: lb://product-service  # 负载均衡到product-servicepredicates:- Path=/api/product/**filters:- StripPrefix=2  # 去除路径前缀/api/product- id: order-serviceuri: lb://order-service  # 负载均衡到order-servicepredicates:- Path=/api/order/**filters:- StripPrefix=2  # 去除路径前缀/api/order- id: admin-serviceuri: lb://admin-service  # 负载均衡到admin-servicepredicates:- Path=/admin/**filters:- StripPrefix=1  # 去除路径前缀/admin# 全局过滤器配置globalcors:cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods: "*"allowedHeaders: "*"server:port: 8080  # 网关端口

7. 服务调用与集成

使用OpenFeign实现服务间调用:

// order-service/src/main/java/com/ecommerce/order/feign/UserServiceClient.java
package com.ecommerce.order.feign;import com.ecommerce.user.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** 用户服务Feign客户端*/
@FeignClient(name = "user-service")  // 服务名称
public interface UserServiceClient {/*** 获取用户信息* @param id 用户ID* @return 用户信息*/@GetMapping("/api/user/{id}")User getById(@PathVariable("id") Long id);
}

在订单服务中使用Feign客户端:

// order-service/src/main/java/com/ecommerce/order/service/OrderServiceImpl.java
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate OrderDao orderDao;@Autowiredprivate UserServiceClient userServiceClient;@Overridepublic Order getOrderDetail(Long orderId) {Order order = orderDao.findById(orderId).orElse(null);if (order != null) {// 通过Feign调用用户服务获取用户信息User user = userServiceClient.getById(order.getUserId());order.setUser(user);}return order;}
}

8. 分布式事务处理

使用Seata实现分布式事务:

// order-service/src/main/java/com/ecommerce/order/service/OrderService.java
@Service
public class OrderService {@Autowiredprivate OrderDao orderDao;@Autowiredprivate ProductService productService;@Autowiredprivate AccountService accountService;/*** 创建订单(分布式事务)*/@GlobalTransactional  // 开启全局事务public void createOrder(OrderDTO orderDTO) {// 1. 创建订单Order order = new Order();order.setUserId(orderDTO.getUserId());order.setProductId(orderDTO.getProductId());order.setCount(orderDTO.getCount());order.setMoney(orderDTO.getMoney());order.setStatus(0);  // 订单状态:0-创建中,1-已完成orderDao.save(order);// 2. 扣减库存productService.reduceStock(orderDTO.getProductId(), orderDTO.getCount());// 3. 扣减账户余额accountService.reduceBalance(orderDTO.getUserId(), orderDTO.getMoney());// 4. 更新订单状态为已完成order.setStatus(1);orderDao.updateStatus(order.getId(), 1);}
}

9. 服务监控与熔断

配置Sentinel实现服务熔断和限流:

# application.yml
spring:cloud:sentinel:transport:dashboard: localhost:8080  # Sentinel控制台地址port: 8719  # 与Sentinel控制台通信的端口

添加熔断降级注解:

@Service
public class ProductService {@Autowiredprivate ProductDao productDao;@SentinelResource(value = "getProductById", blockHandler = "handleBlock")public Product getProductById(Long id) {// 业务逻辑}/*** 熔断降级处理方法*/public Product handleBlock(Long id, BlockException ex) {// 降级逻辑return new Product();}
}

10. 日志收集与分析平台

下面是ELK日志收集系统的配置:

# logstash.conf
input {file {path => "/var/log/ecommerce/*.log"start_position => "beginning"codec => json}
}filter {mutate {remove_field => ["path", "host", "@version"]}date {match => ["timestamp", "ISO8601"]target => "@timestamp"}
}output {elasticsearch {hosts => ["localhost:9200"]index => "ecommerce-%{+YYYY.MM.dd}"}
}

Kibana配置:

# kibana.yml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
kibana.index: ".kibana"

11. 系统部署与性能优化

使用Docker打包服务:

# Dockerfile
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Docker Compose部署整个系统:

version: '3'
services:gateway-service:build: ./gateway-serviceports:- "8080:8080"depends_on:- nacos- redis- mysqlnetworks:- ecommerce-networkuser-service:build: ./user-serviceports:- "8081:8081"depends_on:- nacos- redis- mysqlnetworks:- ecommerce-networkproduct-service:build: ./product-serviceports:- "8082:8082"depends_on:- nacos- redis- mysql- elasticsearchnetworks:- ecommerce-networkorder-service:build: ./order-serviceports:- "8083:8083"depends_on:- nacos- redis- mysql- rocketmqnetworks:- ecommerce-network# 其他服务配置...networks:ecommerce-network:driver: bridge

12. 高级主题实现

服务网格(Istio)配置示例:

# Gateway配置
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: ecommerce-gateway
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "ecommerce.example.com"

分布式缓存配置:

@Configuration
public class CacheConfig extends CachingConfigurerSupport {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置键的序列化方式template.setKeySerializer(new StringRedisSerializer());// 设置值的序列化方式Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);jsonSerializer.setObjectMapper(om);template.setValueSerializer(jsonSerializer);template.afterPropertiesSet();return template;}
}

总结

通过这个电商系统实战项目,主要掌握了以下技能:

  1. 微服务架构设计与实现
  2. 服务注册与发现
  3. 服务间通信与调用
  4. 分布式事务处理
  5. 消息队列应用
  6. 缓存优化
  7. API网关开发
  8. 服务监控与熔断
  9. 日志收集与分析
  10. 系统部署与性能优化

这个项目涵盖了电商系统的核心功能,可以在此基础上继续扩展更多功能,如营销活动、支付集成、物流管理等。


推荐阅读:《Java小白学习成长之路》

相关文章:

【!!!!终极 Java 中间件实战课:从 0 到 1 构建亿级流量电商系统全链路解决方案!!!!保姆级教程---超细】

终极 Java 中间件实战课&#xff1a;电商系统架构实战教程 电商系统架构实战教程1. 系统架构设计1.1 系统模块划分1.2 技术选型 2. 环境搭建2.1 开发环境准备2.2 基础设施部署 3. 用户服务开发3.1 创建Maven项目3.2 创建用户服务模块3.3 配置文件3.4 实体类与数据库设计3.5 DAO…...

HarmonyOs开发之———使用HTTP访问网络资源

谢谢关注&#xff01;&#xff01; 前言&#xff1a;上一篇文章主要介绍HarmonyOs开发之———Video组件的使用:HarmonyOs开发之———Video组件的使用_华为 video标签查看-CSDN博客 HarmonyOS 网络开发入门&#xff1a;使用 HTTP 访问网络资源 HarmonyOS 作为新一代智能终端…...

Java Queue 接口实现

Date: 2025.05.14 20:46:38 author: lijianzhan Java中的Queue接口是位于java.util包中&#xff0c;它是一个用于表示队列的接口。队列是一种先进先出&#xff08;First-In-First-Out, 简称为FIFO&#xff09;的数据结构&#xff0c;其中元素被添加到队列的尾部&#xff0c;并从…...

【IDEA】注释配置

1. IDEA注释调整&#xff0c;去掉默认在第一列显示 修改为如下&#xff1a; 2. IDEA中修改代码中的注释颜色...

day25 python异常处理

目录 Python 的异常处理机制 核心概念 常见的异常处理结构 try-except try-except-else 常见异常类型 SyntaxError&#xff08;语法错误&#xff09; NameError&#xff08;名称错误&#xff09; TypeError&#xff08;类型错误&#xff09; ValueError&#xff08;值…...

【测试】BUG

目录 1、描述BUG的要素&#xff1a; 2、BUG的级别 3、BUG的状态的流转 4、与开发产⽣争执怎么办&#xff08;⾼频考题&#xff09; 什么是BUG&#xff1f;&#xff1f;&#xff1f; 程序与规格说明之间的不匹配才是错误 1、描述BUG的要素&#xff1a; 问题出现的版本、问…...

Java面向对象三大特性深度解析

Java面向对象三大特性封装继承多态深度解析 前言一、封装&#xff1a;数据隐藏与访问控制的艺术1.1 封装的本质与作用1.2 封装的实现方式1.2.1 属性私有化与方法公开化1.2.2 封装的访问修饰符 二、继承&#xff1a;代码复用与类型扩展的核心机制2.1 继承的定义与语法2.2 继承的…...

C 语言学习笔记(8)

内容提要 数组 数组的概念一维数组 数组 数组的概念 什么是数组 数组是相同类型&#xff0c;有序数据的集和 数组的特征 数组中的数据被称之为数组的元素&#xff08;所谓的元素&#xff0c;其实就是数组的每一个匿名的变量空间&#xff09;&#xff0c;是同构。数组中的…...

Screen Mirroring App:轻松实现手机与电视的无缝投屏

Screen Mirroring App 是一款由2kit consulting发行的电视投屏软件&#xff0c;专为用户提供便捷的投屏解决方案。它支持将手机和平板屏幕上的内容实时投射到大电视上&#xff0c;无论是观看影视作品、玩游戏、浏览照片还是阅读电子书&#xff0c;都能提供清晰、稳定的画质和流…...

html js 原生实现web组件、web公共组件、template模版插槽

在现代浏览器中&#xff0c;通过 class 继承 HTMLElement 可以轻松创建原生 Web Components&#xff08;自定义元素&#xff09;&#xff0c;并能享受与普通 HTML 元素同等的语义和性能优势。下面将从核心概念、生命周期方法、Shadow DOM、表单关联、自定义属性、以及与 Vue 3 …...

【爬虫】DrissionPage-2

之前的三个对象是4.0版本&#xff0c;看到的是网上大佬们网上的文章&#xff0c;因为看到官网更新了4.1&#xff0c;我觉得有必要了解一下&#xff1a;文档地址&#xff1a;&#x1f4a5; 4.1 功能介绍 | DrissionPage官网 点击链接看官网就行&#xff0c;下面一样的。 4.1 的…...

鸿蒙OSUniApp 制作个人信息编辑界面与头像上传功能#三方框架 #Uniapp

UniApp 制作个人信息编辑界面与头像上传功能 前言 最近在做一个社交类小程序时&#xff0c;遇到了需要实现用户资料编辑和头像上传的需求。这个功能看似简单&#xff0c;但要做好用户体验和兼容多端&#xff0c;还是有不少细节需要处理。经过一番摸索&#xff0c;总结出了一套…...

系统漏洞扫描服务:维护网络安全的关键与服务原理?

系统漏洞扫描服务是维护网络安全的关键措施&#xff0c;能够迅速发现系统中的潜在风险&#xff0c;有效预防可能的风险和损失。面对网络攻击手段的日益复杂化&#xff0c;这一服务的重要性日益显著。 服务原理 系统漏洞扫描服务犹如一名恪尽职守的安全守护者。它运用各类扫描…...

[原创](现代C++ Builder 12指南): 在界面开发中, 如何利用C++高级特性“折叠表达式“?.

[序言] 在现代C++编程中, 现代C++引入的折叠表达式(Fold Expressions)是一项极具价值的特性, 它为模板编程带来了更高的灵活性和简洁性. 折叠表达式允许在参数包上执行简洁的折叠操作, 从而减少冗余代码, 提升代码的可读性与维护性. 在界面开发领域, 特别是使用C++ Builder 12进…...

KUKA机器人中断编程3—暂停功能的编程

在KUKA机器人的使用过程中&#xff0c;对于调试一个项目&#xff0c;当遇到特殊情况时需要暂停机器人&#xff0c;等异常情况处理完成后再继续机器人的程序运行。wait for指令是等待一个输入信号指令&#xff0c;没有输入信号&#xff0c;机器人一直等待。在一定程度上程序也不…...

【LeetCode 热题 100】反转链表 / 回文链表 / 有序链表转换二叉搜索树 / LRU 缓存

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;LeetCode 热题 100 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 相交链表反转链表回文链表环形链表环形链表 II合并两个有序链表两数相加删除链表的倒数第 N 个结点两两交换链表中的…...

Seata源码—1.Seata分布式事务的模式简介

大纲 1.Seata分布式事务框架简介 2.Seata AT模式实现分布式事务的机制 3.Seata AT模式下的写隔离机制 4.Seata AT模式下的读隔离机制 5.官网示例说明Seata AT模式的工作机制 6.Seata TCC模式的介绍以及与AT模式区别 7.Seata Saga模式的介绍 8.单服务多个库的分布式事务…...

牛客——签到题

分析 我拿到题就去看了示例&#xff0c;可以发现&#xff0c;并非是让难度最小&#xff0c;或者难度系数出现次数最多的成为签到题的难度。那我就有点懵了。。。。。。 但仔细观察题目本身的特定条件和目标&#xff0c;即在满足选择 m 道题的前提下&#xff0c;尽可能多地选择…...

【idea】调试篇 idea调试技巧合集

前言&#xff1a;之前博主写过一篇idea技巧合集的文章&#xff0c;由于技巧过于多了&#xff0c;文章很庞大&#xff0c;所以特地将调试相关的技巧单独成章, 调试和我们日常开发是息息相关的&#xff0c;用好调试可以事半功倍 文章目录 1. idea调试异步线程2. idea调试stream流…...

k8s监控方案实践补充(一):部署Metrics Server实现kubectl top和HPA支持

k8s监控方案实践补充&#xff08;一&#xff09;&#xff1a;部署Metrics Server实现kubectl top和HPA支持 文章目录 k8s监控方案实践补充&#xff08;一&#xff09;&#xff1a;部署Metrics Server实现kubectl top和HPA支持一、Metrics Server简介二、Metrics Server实战部署…...

直流电机风速仪

在处理直流电机风速仪的 ADC 读取问题时&#xff0c;下面为你详细介绍实现方法。 硬件连接 风速仪的输出通常是模拟信号&#xff0c;所以需要把它连接到微控制器的 ADC 输入引脚。比如&#xff0c;在 Arduino 上可以连接到 A0 - A5 这类模拟输入引脚。 ADC 读取原理 风速仪…...

dify 连接不上ollama An error occurred during credentials validation:

三大报错 An error occurred during credentials validation: HTTPConnectionPool(hosthost.docker.internal, port11434): Max retries exceeded with url: /api/chat (Caused by NameResolutionError("<urllib3.connection.HTTPConnection object at 0x7f26fc3c00b0&…...

19、云端工业物联网生态组件 - 工厂能效与预测维护 - /数据与物联网组件/cloud-iiot-factory-analysis

76个工业组件库示例汇总 云端工业物联网生态组件 - 工厂能效与预测维护 (模拟) 概述 这是一个交互式的 Web 组件&#xff0c;旨在模拟一个云端工业物联网 (IIoT) 平台的核心界面&#xff0c;专注于工厂层面的能效分析和基于传感器数据的预测性维护概念。用户可以监控模拟的设…...

python打卡day25

python的异常处理机制 知识点回顾&#xff1a; 异常处理机制debug过程中的各类报错try-except机制try-except-else-finally机制 在即将进入深度学习专题学习前&#xff0c;我们最后差缺补漏&#xff0c;把一些常见且重要的知识点给他们补上&#xff0c;加深对代码和流程的理解。…...

Jmeter变量传递介绍

文章目录 一、Jmeter变量类型及作用域二、变量传递方式1. 用户定义变量&#xff08;User Defined Variables&#xff09;2. CSV 数据文件&#xff08;CSV Data Set Config&#xff09;3.正则表达式提取器4.后置处理器&#xff08;Post Processor)4.1BeanShell/JSR223 后置处理器…...

机器学习 Day16 聚类算法 ,数据降维

聚类算法 1.简介 1.1 聚类概念 无监督学习&#xff1a;聚类是一种无监督学习算法&#xff0c;不需要预先标记的训练数据 相似性分组&#xff1a;根据样本之间的相似性自动将样本归到不同类别 相似度度量&#xff1a;常用欧式距离作为相似度计算方法 1.2 聚类vs分类 聚类&…...

白日梦:一个方便快捷的将故事制作成视频的工具

我有故事&#xff0c;但我想把它制作成视频&#xff0c;有没有什么好用的工具可以使用呢&#xff1f;如果你也被类似的问题困扰&#xff0c;那么今天分享的这个工具将会解决这个问题。从需求来看&#xff0c;我们希望的是纯文本的故事输入&#xff0c;完整的故事视频输出&#…...

ultralytics中tasks.py---parse_model函数解析

一、根据scale获取对应的深度、宽度和最大通道数 具体例如yaml文件内容如下: depth=0.33,那么重复的模块例如C2f原本重复次数是3,6,6,3,那么T对应的模型重复次数就是三分之一即1,1,2,1次。这个在后面定义的: width=0.25,max_channels=1024 原本c2=64,但经过make_div…...

Codeforces Round 1003 (Div. 4)

A. Skibidus and Amog’u 题目大意 给你一个字符串&#xff0c;把末尾的us换成i 解题思路 删掉最后两个加上“i”即可 代码实现 #include <bits/stdc.h>using i64 long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int …...

基于RFSOC ZU28DR+DSP 6U VPX处理板

板卡概述 基于RFSOC ZU28DRDSP 6U VPX处理板&#xff0c;是一款基于6U VPX总线架构的高速信号处理平台&#xff0c;数模混合信号处理卡&#xff0c;采用 Xilinx ZYNQ UltraScale RFSoC ZU28DR和TI DSP TMS320C6678组合设计&#xff0c;两者之间通过4x 5G SRIO互联。本板卡可实…...

C# 通过脚本实现接口

以前C#脚本用的委托注入模式&#xff0c;今天在AI提示下&#xff0c;尝试用脚本直接实现接口&#xff0c;然后C#可以动态或指定新类型创建接口实现对象。从代码角度看&#xff0c;稍显复杂&#xff0c;但脚本方面显得更简洁和有条理。 引用包需要Microsoft.CodeAnalysis、Micro…...

代码随想录算法训练营Day58

力扣695.岛屿的最大面积【medium】 力扣827.最大人工岛【hard】 一、力扣695.岛屿的最大面积【medium】 题目链接&#xff1a;力扣695.岛屿的最大面积 视频链接&#xff1a;代码随想录 1、思路 和岛屿数量那道题很像&#xff0c;只是递归这边要多一个怎么计算面积&#xff0c…...

若依框架页面

1.页面地址 若依管理系统 2.账号和密码 管理员 账号admin 密码admin123 运维 账号yuwei 密码123456 自己搭建的地址方便大家学习&#xff0c;不要攻击哦&#xff0c;谢谢啊...

redis 缓存穿透,缓存击穿,缓存雪崩

一&#xff1a;什么是缓存 &#xff08;1&#xff09;计算机&#xff1a;cpu、内存、磁盘&#xff0c;cpu任何需要的数据都要从内容中读入数据放入cpu,从cup内部添加一个缓存 &#xff08;2&#xff09;web开发的每个阶段都可以添加缓存 &#xff08;3&#xff09;缓存优缺点&a…...

ORACLE查看归档是否打开

一、使用V$DATABASE视图 SELECT log_mode FROM v$database; 结果说明&#xff1a; ARCHIVELOG - 数据库处于归档模式 NOARCHIVELOG - 数据库处于非归档模式 二、 使用v$instance视图 SELECT archiver FROM v$instance; 结果说明&#xff1a; STARTED - 归档进程已启动(归档模…...

Python环境管理工具深度指南:pip、Poetry、uv、Conda

Python环境管理工具深度指南&#xff1a;pip、Poetry、uv、Conda Python开发中&#xff0c;环境管理和依赖管理是不可避开的重要话题。合理地管理项目的Python环境&#xff08;尤其是虚拟环境&#xff09;有助于隔离不同项目的依赖&#xff0c;避免版本冲突&#xff0c;并确保…...

高等数学第七章---微分方程(§7.4-§7.5可降阶的高阶微分方程、二阶线性微分方程)

7.4 可降阶的高阶微分方程 某些类型的高阶微分方程可以通过适当的变量代换&#xff0c;将其阶数降低&#xff0c;从而化为阶数较低的方程进行求解。 一、 y ( n ) f ( x ) y^{(n)}f(x) y(n)f(x) 型方程 特征&#xff1a;方程的左端是 y y y 的 n n n 阶导数&#xff0c;右…...

Jmeter对服务端进行压测快速上手

安装 下载 安装jmeter的之前必须先装有JDK 官网下载地址&#xff1a;https://archive.apache.org/dist/jmeter/binaries/ jmeter3.0的对应jdk1.7&#xff0c;jmeter4.0对应jdk1.8以上&#xff0c;否者启用jmeter也会报错 配置 配置环境变量 在系统变量PATH上加上: %JMET…...

【嵌入模型与向量数据库】

目录 一、什么是向量&#xff1f; 二、为什么需要向量数据库&#xff1f; 三、向量数据库的特点 四、常见的向量数据库产品 FAISS 支持的索引类型 vs 相似度 五、常见向量相似度方法对比 六、应该用哪种 七、向量数据库的核心逻辑 &#x1f50d; 示例任务&#xff1a;…...

鸿蒙OSUniApp 开发实时聊天页面的最佳实践与实现#三方框架 #Uniapp

使用 UniApp 开发实时聊天页面的最佳实践与实现 在移动应用开发领域&#xff0c;实时聊天功能已经成为许多应用不可或缺的组成部分。本文将深入探讨如何使用 UniApp 框架开发一个功能完善的实时聊天页面&#xff0c;从布局设计到核心逻辑实现&#xff0c;带领大家一步步打造专…...

React构建组件

React构建组件 React 组件构建方式详解 React 组件的构建方式随着版本迭代不断演进&#xff0c;目前主要有 函数组件 和 类组件 两种核心模式&#xff0c;并衍生出多种高级组件设计模式。以下是完整的构建方式指南&#xff1a; 文章目录 React构建组件React 组件构建方式详解…...

auto.js面试题及答案

以下是常见的 Auto.js 面试题及参考答案&#xff0c;涵盖基础知识、脚本编写、运行机制、权限、安全等方面&#xff0c;适合开发岗位的技术面试准备&#xff1a; 一、基础类问题 什么是 Auto.js&#xff1f;它的主要用途是什么&#xff1f; 答案&#xff1a; Auto.js 是一个…...

OPC UA + ABP vNext 企业级实战:高可用数据采集框架指南

&#x1f680;&#x1f4ca; OPC UA ABP vNext 企业级实战&#xff1a;高可用数据采集框架指南 &#x1f680; &#x1f4d1; 目录 &#x1f680;&#x1f4ca; OPC UA ABP vNext 企业级实战&#xff1a;高可用数据采集框架指南 &#x1f680;一、前言 &#x1f3af;二、系统…...

【springcloud学习(dalston.sr1)】Ribbon负载均衡(七)

该系列项目整体介绍及源代码请参照前面写的一篇文章【springcloud学习(dalston.sr1)】项目整体介绍&#xff08;含源代码&#xff09;&#xff08;一&#xff09; &#xff08;一&#xff09;Ribbon 负载均衡的理解 ribbon是一种客户端的负载均衡。类似于比如我们在火车站窗口…...

编程题 03-树1 树的同构【PAT】

文章目录 题目输入格式输出格式输入样例1&#xff08;对应图一&#xff09;输出样例1输入样例2&#xff08;对应图二&#xff09;输出样例2 题解解题思路完整代码 编程练习题目集目录 题目 给定两棵树 T 1 T_1 T1​ 和 T 2 T_2 T2​ 。如果 T 1 T_1 T1​ 可以通过若干次左右…...

团结引擎开源车模 Sample 发布:光照渲染优化 动态交互全面体验升级

光照、材质与交互效果的精细控制&#xff0c;通常意味着复杂的技术挑战&#xff0c;但借助 Shader Graph 14.1.0(已内置在团结引擎官方 1.5.0 版本中)&#xff0c;这一切都变得简单易用。通过最新团结引擎官方车模 Sample&#xff0c;开发者能切身感受到全新光照优化与编辑功能…...

Chrome安装最新vue-devtool插件

本vue-devtool版本是官方的 v7.6.8版本&#xff0c;兼容性好、功能齐全且稳定。 操作步骤&#xff1a; 方法一&#xff1a; 打开谷歌浏览器 --> 右上角三个点 --> 扩展程序 --> 管理扩展程序 --> 加载已解压的扩展程序&#xff0c; 然后选择解压后的文件夹即可。…...

鸿蒙OSUniApp打造多功能图表展示组件 #三方框架 #Uniapp

使用UniApp打造多功能图表展示组件 在当前移动应用开发领域&#xff0c;数据可视化已成为不可或缺的一部分。无论是展示销售数据、用户增长趋势还是其他业务指标&#xff0c;一个优秀的图表组件都能有效提升用户体验。UniApp作为一款跨平台开发框架&#xff0c;如何在其中实现…...

海量数据Top k 与查重问题

海量数据求top k 问题&#xff1a; - 求最大的前k个元素、求最小的前k个元素 - 求最大的第k个元素、求最小的第k个元素 解法&#xff1a; - 大根堆、小跟堆 -》 优先级队列&#xff08;priority_queue&#xff09; - 快速分割函数 priority_queue<int,vector<int>…...

Beats

Beats是一个开放源代码的数据发送器。我们可以把Beats作为一种代理安装在我 们的服务器上&#xff0c;这样就可以比较方便地将数据发送到Elasticsearch或者Logstash 中。Elastic Stack提供了多种类型的Beats组件。 Beats可以直接将数据发送到Elasticsearch或者发送到Logstash&a…...