Category: Tech

35 Posts

Ubuntu 非root远程登录
服务器使用Ubuntu,做点简单处理,使用非root用户。 ssh远程登录 首先保证能通过root连接,可用root用户执行以下命令: chown root:root -R /root/.ssh/ chmod 700 /root/.ssh/ chmod 600 /root/.ssh/authorized_keys chown me:me -R /home/lingdou/.ssh/ chmod 700 /home/me/.ssh/ chmod 600 /home/me/.ssh/authorized_keys 其中 me 是要登录的用户名,需要提前创建好。 将用户加入sudo gpasswd -a me sudo echo "me ALL=(ALL) NOPASSWD: ALL" | (EDITOR="tee -a" visudo) 禁用密码和root登录 修改 /etc/ssh/sshd_config : PermitRootLogin no PasswordAuthentication no 重启服务:service sshd restart
mysql 5.7 Disable ONLY_FULL_GROUP_BY
参考链接 修改 /etc/mysql/mysql.conf.d/mysqld.cnf文件,添加: [mysqld] sql-mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" 注:低版本的(可能小于5.7.18)添加的是: [mysqld] sql_mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" sql-mode 和 sql_mode的区别。 不确定的都试一下。 这个配置是mysql docker容器的配置文件,如果是host直接安装的,需要改自己的配置文件。另外,[mysqld]是已经存在的,就只加下面的就可以了。 改完记得重启容器。
清空quartz数据库
表顺序如下: delete from qrtz_CRON_TRIGGERS where 1=1; delete from qrtz_SIMPLE_TRIGGERS where 1=1; delete from qrtz_TRIGGERS where 1=1; delete from qrtz_JOB_DETAILS where 1=1; delete from qrtz_FIRED_TRIGGERS where 1=1; delete from qrtz_LOCKS where 1=1; delete from qrtz_SCHEDULER_STATE where 1=1; delete from qrtz_BLOB_TRIGGERS where 1=1; delete from qrtz_CALENDARS where 1=1; delete from qrtz_PAUSED_TRIGGER_GRPS where 1=1; delete from qrtz_SIMPROP_TRIGGERS where 1=1; 或者: SET FOREIGN_KEY_CHECKS=0; DELETE FROM `qrtz_locks` where 1=1; DELETE FROM `qrtz_paused_trigger_grps` where 1=1; DELETE FROM `qrtz_scheduler_state` where 1=1; DELETE FROM `qrtz_calendars` where 1=1; DELETE FROM `qrtz_job_details` where 1=1; DELETE FROM `qrtz_triggers` where 1=1; DELETE FROM `qrtz_blob_triggers` where 1=1; DELETE FROM `qrtz_cron_triggers` where 1=1; DELETE FROM `qrtz_simple_triggers` where 1=1; DELETE FROM `qrtz_simprop_triggers` where 1=1; DELETE FROM `qrtz_fired_triggers` where 1=1; SET FOREIGN_KEY_CHECKS=0;
tmux plugins tpm启动时报错解决
使用的时zsh,配合oh-my-zsh,在wsl2 Ubuntu20 环境,使用Windows Terminal作为终端。 每次启动电脑后,打开终端,执行tmux后会报错: ~/.tmux/plugins/tpm/tpm' returned 1 网上找的解决方案是需要执行: cd .tmux/plugins/tpm sh -x tpm 试了在zsh启动时自动执行这个命令,但是没用,暂时只能每次手动执行。。
Ubuntu修改hostname
什么是hostname? 打开终端,使用bash,每行开始都是 用户名@xxxx,@后面的就是hostname。 当你有多台服务器,每台服务器作用不一样,并且需要同时登录多台服务器的时候,通过hostname来区分服务器,还是非常有必要的。 修改 使用hostnamectl命令: # 直接回车 可查看当前的hostname hostnamectl # 设置,执行后会修改/etc/hostname文件 hostnamectl set-hostname new-hostname # 然后手动修改/etc/hosts文件 # 替换其中的原hostname为新的hostname # 修改后,不需要重启服务器,退出ssh连接,重新连接即可 参考 点击打开参考链接
Nestjs 使用node-config&dotenv
封装config库,在项目其它app内使用。配合docker部署,效果更好。 // libs/config/src/config.module.ts import { resolve } from 'path'; import { Module } from '@nestjs/common'; import { IConfig } from 'config'; import * as dotenv from 'dotenv'; const path = resolve(__dirname, '..', '..', '..'); dotenv.config(); // config目录放在 apps libs 同级,config内的文件,和config库的配置完全一致 process.env['NODE_CONFIG_DIR'] = resolve(path, 'config'); /* eslint @typescript-eslint/no-var-requires: "off" */ const config = require('config'); config.env.current = process.env.NODE_ENV || 'development'; config.env.app = process.env.NODE_APP_INSTANCE; config.env.isProduction = process.env.NODE_ENV === 'production'; config.env.isProd = process.env.NODE_APP_INSTANCE === 'production' && process.env.NODE_ENV === 'production'; // 这个是挂载一个config目录下的文件路径,方便使用 config.env.wsdl = resolve(path, 'config', 'SMS.wsdl'); const provider = { // 这个地方可以写常量,方便其它地方使用 provide: 'NODE_CONFIG', useValue: config, }; @Module({ providers: [provider], exports: [provider], }) export class ConfigModule {} export type IConfig = IConfig; // libs/config/src/index.ts export * from './config.module'; // 这个是创建config lib 的时候自动生成的,其它的自动生成的文件都可以删除,这个留着就可以了 { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": true, "outDir": "../../dist/libs/config" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] } 注意,使用docker部署时,需要把config目录复制到容器内,因为config目录不会被build到dist中。
Nestjs入门
依赖注入几种方式。 封装为库 以pulsar的使用为例。特点:需要注入配置,创建client单例。 实现方式:在module中定义static register方法,返回DynamicModule。 static register(options: any): DynamicModule { return { // 封装的模块的名字,即当前模块的名字 module: PulsarModule, imports: options.imports || [], providers: [ { // 可以在其它模块使用此字符串注入 provide: 'PULSAR_CLIENT_URL', useFactory: options.useFactory, inject: options.inject, }, ], }; } 然后在对应service中提供client的方法: import { Injectable, Inject } from '@nestjs/common'; import { Client, Consumer, Producer, ProducerOpts, SubscribeOpts, } from 'pulsar-client'; @Injectable() export class PulsarService { pulsar: Client; constructor(@Inject('PULSAR_CLIENT_URL') private url) { this.pulsar = new Client({ serviceUrl: url }); } async buildConsumer(options: SubscribeOpts): Promise<Consumer> { return this.pulsar.subscribe(options); } async buildProducer(options: ProducerOpts): Promise<Producer> { return this.pulsar.createProducer(options); } async closeArr(arr: Consumer[] | Producer[]) { if (!arr || !arr.length) return; for (const ele of arr) ele.close(); } async close(consumers?: Consumer[], producers?: Producer[]) { this.closeArr(consumers); this.closeArr(producers); if (this.pulsar) { this.pulsar.close(); } } } 关于pulsar,一个消息中间件,已经封装为一个npm库,欢迎使用,star。https://www.npmjs.com/package/nestjs-pulsar
初始化WSL 2 + nodejs
Deprecated @see 发行版:Ubuntu 20.04 系统更新 # cat EOF 用法:https://blog.csdn.net/lym152898/article/details/83306993 mv /etc/apt/sources.list /etc/apt/sources.list.bak sudo su cat > /etc/apt/sources.list <<EOF # 中科大 @see https://www.cnblogs.com/leeyazhou/p/12976814.html deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse EOF exit sudo apt update sudo apt upgrade 编译安装vim https://www.ilaipi.top/2019/11/22/vim-%e7%bc%96%e8%af%91%e5%ae%89%e8%a3%85-python3%e6%94%af%e6%8c%81/ 安装zsh sudo apt install zsh 安装nvm&node https://github.com/nvm-sh/nvm 下载install.sh,然后执行: bash install.sh 安装vim套件 mkdir Applications && cd Applications git clone git@git.zhlh6.cn:vim/vim.git --depth=1 # github加速插件提供的加速地址 git clone git@github.com:ilaipi/k-vim.git --depth=1 git clone git@github.com:ilaipi/k-tmux.git --depth=1 https://github.com/ohmyzsh/ohmyzsh/tree/master/tools # 先下载 install.sh 然后执行 sh -c install.sh git clone git@git.zhlh6.cn:ilaipi/dotfiles.git cd dotfiles && sh -x intall.sh git clone git@git.zhlh6.cn:tmux/tmux.git --depth=1 # install tmux @see https://github.com/tmux/tmux sudo apt install automake sudo apt install build-essential sudo apt-get install pkg-config sudo apt install libevent-dev sudo…
身份证号校验
function validate(code) { var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; var parity = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; var sum = 0; var i = 0; if (!/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) { return false; } for (i = 0; i < 17; i = i + 1) { sum += code.charAt(i) * factor[i]; } return parity[sum % 11] === code[17].toUpperCase(); } 按照算法,严格校验身份证。
使用WebSocket
客户端:微信小程序 服务器:eggjs+egg-socket.io 弄清楚几个概念。 namespace // client import io from 'weapp.socket.io'; // 请求服务器的 'chat' namespace const server = io('ws://localhost:7001/chat', { transports: ['websocket'], }); // server // 监听 'chat' namespace下的 one-event-name 事件 app.io.of('chat').route('one-event-name', xxx); path 这个相当于http的请求路径。 // client const server = io('ws://localhost:7001/chat', { path: '/socket', // default: socket.io transports: ['websocket'], }); // server based on eggjs config.io = { init: { path: '/socket', }, }; // server based on socket.io directly const Server = require('socket.io'); const io = Server({ path: '/socket', serveClient: false }); 在服务端需要根据这个path做反向代理,比如: location /socket { proxy_pass socket_server_address; // 支持socket协议的服务 } 使用的时候,约定好namespace,一般应用用一个namespace就可以。多个namespace可以使用同一个socket连接,也可以使用多个: // @see https://github.com/socketio/socket.io-client/blob/master/docs/API.md // By default, a single connection is used when connecting to different namespaces (to minimize resources): const socket = io(); const adminSocket = io('/admin'); // a single connection will be established // That behaviour can be disabled with the forceNew option: const socket = io(); const adminSocket = io('/admin', { forceNew: true }); // will create two distinct connections // Note: reusing the same namespace will also create two connections const socket = io(); const socket2 = io(); // will…