회원가입시 인증 코드를 이메일로 발송하기 전 , 큐에 담고 가입을 먼저 시킨 후 발송

 async signUp(
    email: string,
    password: string,
    passwordConfirm: string,
    nickName: string,
    birth: string,
  ) {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    const existingUser = await this.usersService.findByEmail(email);
    if (existingUser) {
      throw new ConflictException(
        '이미 해당 이메일로 가입된 사용자가 있습니다!',
      );
    }
    if (password !== passwordConfirm) {
      throw new UnauthorizedException(
        '비밀번호가 체크비밀번호와 일치하지 않습니다.',
      );
    }

    try {
      const hashedPassword = await hash(password, 10);

      const user = await queryRunner.manager.getRepository(Users).save({});

      await queryRunner.manager.getRepository(UserInfos).save({
        id: user.id,
        email: email,
        password: hashedPassword,
        nickName: nickName,
        birth: birth,
        verifiCationCode: 0,
        user: user,
      });

      await queryRunner.commitTransaction();

      await this.AuthenticationNumberCache(email);

      return user;
    } catch (error) {
      await queryRunner.rollbackTransaction();
    } finally {
      await queryRunner.release();
    }
  }

이메일 서비스에 있는 메서드로 이동 ,

 async AuthenticationNumberCache(email: string) {
    const code = Math.floor(Math.random() * 900000) + 100000;

    await this.cacheManager.set(email, code, 1000 * 60 * 60 * 3);

    await this.emailService.queueVerificationEmail(email, code);
  }

큐 시스템 사용

 async queueVerificationEmail(email: string, code: number) {
    await this.emailQueue.add(
      'sendVerificationEmail',
      { email, code },
      {
        attempts: 5,
        backoff: {
          type: 'exponential',
          delay: 1000,
        },
      },
    );
  }