高可用、高并发电商系统的大致架构以及关键部分示例代码

一、整体架构概述

  1. 前端层:包括电商网站的页面展示、移动端 APP 等,通过 API 网关与后端微服务进行交互,负责向用户呈现商品信息、处理用户操作等。
  2. API 网关层(Spring Cloud Gateway):作为所有请求的入口,负责路由转发、鉴权、限流等功能,将不同的请求分发到对应的后端微服务上,实现统一的接口管理与安全控制。
  3. 微服务层(Spring Cloud + Dubbo)
    • 商品服务:负责商品信息的管理,包括商品的添加、删除、查询、修改等操作,与数据库交互获取商品数据,并可利用 Redis 进行缓存加速热门商品的查询。
    • 订单服务:处理订单的创建、支付、查询、取消等流程,可能会涉及到分布式事务的处理(可结合 Seata 等框架来实现),同时与消息队列(如 RabbitMQ 或 Kafka)交互,用于异步处理订单相关业务,比如通知库存扣减等。
    • 用户服务:管理用户的注册、登录、信息修改、权限验证等功能,也可使用 Redis 缓存用户登录态等信息来提升性能。
    • 库存服务:维护商品的库存数量,接收来自订单服务等的库存扣减请求,并更新库存信息,借助分布式锁(基于 Redis 等实现)来保证库存扣减的准确性。
    • 搜索服务(ElasticSearch):提供商品的全文搜索功能,会定期从数据库中将商品数据同步到 ElasticSearch 索引中,方便用户快速搜索到想要的商品。
  4. 服务治理与注册中心(Zookeeper):用于服务的注册与发现,各个微服务启动时将自己的信息注册到 Zookeeper 上,方便其他服务在调用时进行查找和负载均衡,同时配合 Dubbo 实现分布式服务的治理,比如动态配置管理、服务降级等。
  5. 消息队列层(RabbitMQ 或 Kafka):用于解耦微服务之间的依赖关系,实现异步通信,例如订单支付成功后发送消息通知库存服务扣减库存、通知物流服务发货等场景,同时可以处理高并发下的流量削峰,保证系统的稳定性。
  6. 分布式缓存层(Redis):缓存常用数据,如热门商品信息、用户登录态、菜单数据等,减轻数据库压力,提升系统响应速度,并且可用于实现分布式锁等功能保证并发情况下数据的一致性。
  7. 分布式搜索层(ElasticSearch):为商品等数据提供强大的全文搜索功能,通过合理的索引构建与查询优化,满足用户快速查找商品的需求。
  8. 数据存储层:使用关系数据库(如 MySQL)存储核心业务数据,如商品信息、用户信息、订单信息等,同时结合分库分表等策略应对大数据量和高并发读写的情况。

二、关键技术示例代码

1. Spring Cloud 微服务基础配置(以服务注册发现为例,使用 Eureka,实际中可用 Zookeeper 替代,配置类似)

pom.xml 中引入相关依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在启动类上添加注解开启服务注册发现功能:

import org.springframework.boot.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ProductServiceApplication {
    public static void main(String[] args) {
        SpringBootApplication.run(ProductServiceApplication.class, args);
    }
}

配置 application.yml 文件,指定服务注册中心地址等信息(以下以 Eureka 为例,Zookeeper 配置对应修改):

spring:
  application:
    name: product-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

2. Dubbo 服务配置与使用(以商品服务接口和实现为例)

定义商品服务接口:

public interface ProductService {
    Product getProductById(Long productId);
    List<Product> listProducts();
    // 其他商品相关操作方法
}

实现类:

import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;

@Component
@Service(version = "1.0.0")
public class ProductServiceImpl implements ProductService {

    @Override
    public Product getProductById(Long productId) {
        // 从数据库或缓存等获取商品信息的逻辑
        return productDao.findById(productId);
    }

    @Override
    public List<Product> listProducts() {
        // 查询商品列表逻辑
        return productDao.findAll();
    }
}

在消费者端(比如订单服务调用商品服务),注入商品服务接口进行远程调用:

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

@Service
public class OrderServiceImpl implements OrderService {

    @Reference(version = "1.0.0")
    private ProductService productService;

    @Override
    public void createOrder(Order order) {
        Product product = productService.getProductById(order.getProductId());
        // 后续创建订单的其他逻辑
    }
}

3. Zookeeper 作为服务注册中心配置(结合 Dubbo 使用)

dubbo.properties (或 application.yml 等配置文件中配置,以 dubbo.properties 为例):

dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.registry.protocol=zookeeper

4. RabbitMQ 消息队列使用示例(发送消息)

引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置文件 application.yml

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

在代码中发送消息(以订单支付成功后发送消息通知库存服务为例):

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class OrderMessageSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendStockDeductionMessage(Order order) {
        rabbitTemplate.convertAndSend("stock.deduction.exchange", "stock.deduction.routing.key", order);
    }
}

接收消息(库存服务端):

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class StockMessageReceiver {

    @RabbitListener(queues = "stock.deduction.queue")
    public void receiveStockDeductionMessage(Order order) {
        // 处理库存扣减逻辑
        stockService.deductionStock(order.getProductId(), order.getQuantity());
    }
}

5. Redis 缓存使用示例(缓存商品信息)

引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置文件指定 Redis 连接信息(application.yml):

spring:
  redis:
    host: localhost
    port: 6379

在商品服务中使用 Redis 缓存查询逻辑(以查询商品为例):

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private RedisTemplate<String, Product> redisTemplate;
    @Autowired
    private ProductDao productDao;

    @Override
    public Product getProductById(Long productId) {
        String cacheKey = "product:" + productId;
        Product product = redisTemplate.opsForValue().get(cacheKey);
        if (product == null) {
            product = productDao.findById(productId);
            if (product!= null) {
                redisTemplate.opsForValue().set(cacheKey, product);
            }
        }
        return product;
    }
}

6. ElasticSearch 使用示例(商品搜索功能)

引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

配置 application.yml 指定 ElasticSearch 连接信息:

spring:
  data:
    elasticsearch:
      client:
        reactive:
          endpoints: localhost:9200

定义商品搜索的 Repository 接口:

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductSearchRepository extends ElasticsearchRepository<Product, Long> {
    List<Product> findByNameContaining(String keyword);
}

在搜索服务中调用该 Repository 进行搜索:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private ProductSearchRepository productSearchRepository;

    @Override
    public List<Product> searchProducts(String keyword) {
        return productSearchRepository.findByNameContaining(keyword);
    }
}

7. Docker 部署微服务示例(以商品服务为例,编写 Dockerfile)

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/product-service.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

构建镜像并运行容器(在包含 Dockerfile 的目录下执行命令):

docker build -t product-service-image.
docker run -d -p 8080:8080 product-service-image
posted @ 2024-12-18 17:45  软件职业规划  阅读(19)  评论(0编辑  收藏  举报