NestJS 高并发实战:从异步到集群的完整方案


一、前言

NestJS 高并发实战:从异步到集群的完整方案是 Java 后端开发中的核心知识点。本文覆盖NestJS、高并发、后端,配有完整可运行的代码示例。


二、核心实现

2.1 SpringBoot 项目结构

java 复制代码
// 标准 SpringBoot 控制器
@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public Result<UserDTO> getUser(@PathVariable Long id) {
        return Result.ok(userService.getUserById(id));
    }

    @PostMapping
    public Result<Void> createUser(@RequestBody @Valid CreateUserRequest request) {
        userService.createUser(request);
        return Result.ok();
    }
}

2.2 Service 层实现

java 复制代码
@Service
@Slf4j
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    @Transactional(rollbackFor = Exception.class)
    public UserDTO createUser(CreateUserRequest request) {
        // 参数校验
        if (userRepository.existsByEmail(request.getEmail())) {
            throw new BusinessException("邮箱已被注册");
        }

        // 密码加密
        User user = new User();
        user.setEmail(request.getEmail());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setCreatedAt(LocalDateTime.now());

        User saved = userRepository.save(user);
        log.info("创建用户成功: {}", saved.getEmail());
        return toDTO(saved);
    }

    @Cacheable(value = "user", key = "#id")
    public UserDTO getUserById(Long id) {
        return userRepository.findById(id)
            .map(this::toDTO)
            .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
    }

    private UserDTO toDTO(User user) {
        return new UserDTO(user.getId(), user.getEmail(), user.getCreatedAt());
    }
}

三、异常处理与全局响应

3.1 统一异常处理

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusiness(BusinessException e) {
        log.warn("业务异常: {}", e.getMessage());
        return Result.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValidation(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors().stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.joining(", "));
        return Result.fail(400, message);
    }

    @ExceptionHandler(Exception.class)
    public Result<Void> handleOther(Exception e) {
        log.error("未知异常", e);
        return Result.fail(500, "系统繁忙,请稍后重试");
    }
}

3.2 统一响应封装

java 复制代码
@Data
public class Result<T> {
    private int code;
    private String message;
    private T data;

    public static <T> Result<T> ok() {
        return ok(null);
    }

    public static <T> Result<T> ok(T data) {
        Result<T> r = new Result<>();
        r.setCode(0);
        r.setMessage("success");
        r.setData(data);
        return r;
    }

    public static <T> Result<T> fail(int code, String message) {
        Result<T> r = new Result<>();
        r.setCode(code);
        r.setMessage(message);
        return r;
    }
}

四、数据库操作

4.1 MyBatis-Plus CRUD

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<User> {

    @Select("SELECT * FROM users WHERE email = #{email} LIMIT 1")
    User findByEmail(@Param("email") String email);
}

@Service
public class UserService {

    @Autowired private UserMapper userMapper;

    public Page<User> listUsers(int page, int pageSize) {
        Page<User> p = new Page<>(page, pageSize);
        return userMapper.selectPage(p, new QueryWrapper<User>()
            .eq("status", 1)
            .orderByDesc("created_at"));
    }
}

五、性能优化

5.1 连接池配置

yaml 复制代码
# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: secret
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      idle-timeout: 300000
      connection-timeout: 20000
      max-lifetime: 1200000

5.2 异步任务

java 复制代码
@Async("taskExecutor")
public CompletableFuture<Void> sendEmail(String to, String content) {
    log.info("发送邮件到: {}", to);
    // 邮件发送逻辑
    return CompletableFuture.completedFuture(null);
}

六、总结

  1. SpringBoot 的核心是约定优于配置------善用注解和自动配置
  2. 所有外部输入必须校验------用 @Valid + BindingResult
  3. 异常要分类处理------业务异常和系统异常分开
  4. 连接池合理配置------根据并发量调整 pool size

💬 收藏本文!关注我,后续更新更多 Java 实战系列。


💬 觉得有用的话,点个赞+收藏,关注我,持续更新优质技术内容!

标签:NestJS | 高并发 | 后端 | 性能 | 实战

相关推荐
桃西西呀几秒前
Spring AI Alibaba 之七:我没写一行 tracing 埋点,Agent 每一步却被 Micrometer 看得清清楚楚
人工智能·spring·llm
桃西西呀1 分钟前
Spring AI Alibaba 之八:我让 Agent 直接执行 shell 命令,它却读到了目录里的密钥,沙箱到底防住了什么
人工智能·spring·llm
荣码1 分钟前
从0到1搭一个生产级RAG系统:串联前面21篇所有知识
java·python
xuxigifxfh4 分钟前
牛客:HJ170 01序列
java·开发语言·算法·华为机考
code_slave(码畜)17 分钟前
微服务架构落地:消息队列架构设计(下篇)——消息堆积、死信治理与集群监控告警实战
spring boot·spring cloud·微服务·云原生·中间件·架构
野生技术架构师25 分钟前
牛客网互联网大厂 Java 高频面试题整理(持续更新)
java·开发语言
小师兄吃牛肉1 小时前
Java语法 | 多重循环
java·开发语言·python
Han.miracle1 小时前
MySQL InnoDB:MVCC、记录锁、间隙锁、二级索引MVCC底层原理
java·开发语言
不停喝水1 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
y1su2 小时前
Leetcode 二分模板
java·数据结构·算法·leetcode·排序算法