我司最近很多 javaer 的各种微服务需要前端来一个一个调用,这样做岂不是很繁琐?
先说说为什么要做微服务:
结合微服务架构,不仅能够提升系统的可扩展性和可靠性,同时也能促进团队的高效协作与快速迭代,从而更好地应对复杂业务场景。
这样做可以结合他们的服务结合自己的业务紧密配合~
直接 po 代码:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
FastifyAdapter,
NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { HkAuthMiddleware } from './hk-auth/hk-auth.middleware';
import { HttpService } from '@nestjs/axios';
import fastifyMultipart from '@fastify/multipart';
import cluster from 'cluster';
import * as os from 'os';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
async function bootstrap() {
// 创建 Fastify HTTP 应用
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
// 注册微服务连接
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
options: {
host: process.env.SCREENSHOT_SERVICE_HOST || 'localhost',
port: parseInt(process.env.SCREENSHOT_SERVICE_PORT || '4000'),
retryAttempts: 5, // 重试次数
retryDelay: 3000, // 重试延迟(毫秒)
},
});
// 启动微服务连接
await app.startAllMicroservices();
// 保持现有的配置
const httpService = new HttpService();
const authMiddleware = new HkAuthMiddleware(httpService);
app.setGlobalPrefix(`/api`);
await app.register(fastifyMultipart, {
limits: {
fileSize: 200 * 1024 * 1024,
},
});
app.use((req, res, next) => authMiddleware.use(req, res, next));
await app.enableCors();
// 启动 HTTP 服务
await app.listen(3000, '0.0.0.0');
}
// 保持现有的集群模式
if (cluster.isPrimary) {
const cpuCount = os.cpus().length;
console.log(`主进程启动,准备 fork ${cpuCount} 个工作进程`);
for (let i = 0; i < cpuCount; i++) {
cluster.fork();
}
cluster.on('exit', (worker) => {
console.log(`工作进程 ${worker.process.pid} 退出,重启中...`);
cluster.fork();
});
} else {
bootstrap();
}
这里解释一下注册微服务,你可以简单的理解为,你自己开了一家店铺,别人可以来你店里采购你的各种service。
那么 host 就代表你服务器的 Ip、port 及你开启微服务的端口。
这样即可将应用转化为微服务应用~每个工作进程都会同时支持 HTTP 和微服务通信
在服务层建立 tcp 通讯#
这样,我们就可以在服务层去连接其他 javer 的微服务,比如,我们需要把某一个截图功能处理的 base64 存入 redis 或者调用 java 服务。
import { Injectable } from '@nestjs/common';
import { ClientProxy, Transport } from '@nestjs/microservices';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class ScreenshotClient {
private client: ClientProxy;
constructor() {
this.client = new ClientProxy({
transport: Transport.TCP,
options: {
host: process.env.SCREENSHOT_SERVICE_HOST || 'localhost',
port: parseInt(process.env.SCREENSHOT_SERVICE_PORT || '4000'),
},
});
}
async generateScreenshot(groups: any) {
try {
const result = await firstValueFrom(
this.client.send({ cmd: 'generate_screenshot' }, groups)
);
if (!result.success) {
throw new Error(result.error);
}
return result.data;
} catch (error) {
throw new Error(`截图生成失败: ${error.message}`);
}
}
}
client 代表你连接 ip+port 的服务,
send 则表示你发送給对方微服务的消息命令。
如:send ({cmd: 'some_command'}, data)。即可。
当然了,你可以同时在一个服务里调用不同的微服务。
@Injectable()
export class SomeService {
private redisClient: ClientProxy;
private rabbitClient: ClientProxy;
constructor() {
// Redis 微服务客户端
this.redisClient = new ClientProxy({
transport: Transport.REDIS,
options: {
host: '192.168.1.111',
port: 6379,
},
});
// RabbitMQ 微服务客户端
this.rabbitClient = new ClientProxy({
transport: Transport.RMQ,
options: {
urls: ['amqp://192.168.1.222:5672'],
queue: 'my_queue',
},
});
}
}
开放自己的微服务#
比如 javer 对于一个业务需要多次 dto-oto, 那么可以经过我们的服务再做处理:
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import { ScreenshotService } from './screen-shot.service';
@Controller()
export class ScreenshotController {
constructor(private readonly screenshotService: ScreenshotService) {}
// 这是一个微服务端点
@MessagePattern({ cmd: 'generate_screenshot' })
async generateScreenshot(data: any) {
try {
const result = await this.screenshotService.compositeAllGroups(data);
return {
success: true,
data: result
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
// 这是原来的 HTTP 端点,保持不变
@Post()
async httpGenerateScreenshot(@Body() data: any) {
// ... 原有的 HTTP 处理逻辑
}
}
end----
下期出普罗米修斯 + granafa 集成可视化性能监控。