2024s

socket.io多实例集群化实现

月盾

Socket.io作为服务器推送的首要选择,可以很方便的在客户端和Web服务器之间实现双向通信。很多人在选择之初都会有个疑问:socket.io是有状态长链接服务,它能支撑多少个用户同时在线?

虽然目前没有标准统一的答案,但是,在开发实践中已经证明,在单机情况下10万用户是没问题的。

如果您觉得10万还是不够,那么可以通过多实例的方式来支持更多的用户也是可行的。实现方式几乎是零成本升级。

您只需要将默认的适配器更换为redis或其他适配器就可以支持多实例:

一个基于epxress和socket.io的多实例服务配置:

#!/usr/bin/env node

const app = require('../app');
const debug = require('debug')('ws_server:www');
const { createServer } = require('http');
const { Server } = require('socket.io');
const { createAdapter } = require("@socket.io/redis-adapter");
const { Redis } = require("ioredis");

const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

const httpServer = createServer(app);

/**
 * Normalize a port into a number, string, or false.
 */
function normalizePort(val) {
	var port = parseInt(val, 10);
	if (isNaN(port)) {
		// named pipe
		return val;
	}
	if (port >= 0) {
		// port number
		return port;
	}
	return false;
}

/**
 * Event listener for HTTP server "error" event.
 */
function onError(error) {
	if (error.syscall !== 'listen') {
		throw error;
	}

	var bind = typeof port === 'string'
		? 'Pipe ' + port
		: 'Port ' + port;

	// handle specific listen errors with friendly messages
	switch (error.code) {
		case 'EACCES':
			console.error(bind + ' requires elevated privileges');
			process.exit(1);
			break;
		case 'EADDRINUSE':
			console.error(bind + ' is already in use');
			process.exit(1);
			break;
		default:
			throw error;
	}
}

/**
 * Event listener for HTTP server "listening" event.
 */
function onListening() {
	var addr = httpServer.address();
	var bind = typeof addr === 'string'
		? 'pipe ' + addr
		: 'port ' + addr.port;
	console.log('Listening on ' + bind);
}
// 重点部分
const pubClient = new Redis({
	host: process.env.REDIS_HOST,
	port: process.env.REDIS_PORT,
	password: process.env.REDIS_PASSWORD,
});
const subClient = pubClient.duplicate();

const io = new Server(httpServer, {
	adapter: createAdapter(pubClient, subClient),
	cors: {
		origin: ["https://admin.socket.io", "http://127.0.0.1:8080"],
		// allowedHeaders: ["Authorization", "Cookie"],
		credentials: true
	}
});

app.set("IO", io);

httpServer.listen(port);
httpServer.on('error', onError);
httpServer.on('listening', onListening);

经过上面的改动后,所有的socket.io服务器实例可以共享一个redis实例来存储连接的状态信息。

gitlab-ci使用Harbor机器人账户

月盾

gitlab ci/cd 中,需要使用到 docker registry 账号 push 镜像,这个可以设置为机器人,可以避免个人账号泄露

配置Harbor机器人

  • 登录 Harbor 管理界面,进入系统管理→认证页面;
  • 选择机器人 Token页签,点击左上角的新建机器人,创建一个名为gitlab-ci的机器人;
  • 给该机器人一个名称,并给该机器人添加相应的权限;
  • 机器人创建完成以后,点击右侧的查看token来复制该机器人的 token,这个就是以后用 gitlab-ci 配置文件使用的账号密码;
  • 在gitlab 创建 harbor-robot 用户;
  • 为该用户添加项目级别的 开发 权限;

配置gitlab-ci

  • 在项目的设置中添加 docker registry 账号密码,仓库地址是harbor的;
  • 编辑.gitlab-ci.yml文件,把账号密码改为之前复制的 token;

注意点

有些情况下创建的机器人账户会带上$符号,在gitlab中是无法使用的,需要将$改为两个$$来表示$

结束

这样gitlab-ci 就可以顺利跑测试、构建、推送镜像了;

以上内容,只是简单的配了配 harbor,可以有很多其他方法完成该工作,这里只是简单的记录下而已;

如果需要复杂的设置,欢迎移步harbor 文档,那里有更多的内容可以提供参考。

微信小程序页面之间传递数据和通信

月盾

微信小程序页面间通信有标准的方法。 有页面A,页面B,按照顺序,A -> B,再从B -> A。两种操作页面之间数据传递。

A页面:

Page({
  jump: function () {
    wx.navigateTo({
      url: './b-page?id=123',
      events: {
        acceptDataFromOpenedPage: function (data) {
          //接收B页面发送的数据
          console.log(data)
        },
      },
      success: function (res) {
        //页面打开后发送数据到B页面
        res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'send from opener page' })
      }
    })
  },
})

B页面:

Page({
  onLoad: function (option) {
    const id = option.id;// 通过URL参数获取A页面传递的数据
    const eventChannel = this.getOpenerEventChannel()
    eventChannel.on('acceptDataFromOpenerPage', function (data) {
      //通过事件channel接收A页面传递的数据
      console.log(data)
    })
  },
  setDataToA: function () {
    const eventChannel = this.getOpenerEventChannel()
    eventChannel.emit('acceptDataFromOpenedPage', { data: 'send from opened page' })
  },
})
又一个比Nodejs快的运行时,它叫LLRT

又一个比Nodejs快的运行时,它叫LLRT

月盾

前端圈的发展一向让人感觉学不动,前有Deno,后有Bun,这不,最近又出了个比Nodejs快的Runtime,它叫LLRT。

node deno bun对比

1. 什么是LLRT

LLRT是Low Latency Runtime的缩写,是一种轻量级JavaScript运行时,旨在满足对快速高效的无服务器应用程序日益增长的需求。与在AWS Lambda上运行的其他JavaScript运行时相比,LLRT的启动速度提高了10倍以上,总体成本降低了2倍。

2. LLRT是如何做到比Nodejs快的

它内置在Rust中,利用QuickJS作为JavaScript引擎,确保高效的内存使用和快速启动。

3. LLRT的发展

它还处于实验阶段,并不稳定,还不推荐用于生产。