分类 软件 下的文章
RabbitMQ部署手册
Docker部署
创建自签名证书
生成CA私钥和CA证书
[root@ecs ~]# mkdir -p /data/rabbitmq/ssl && cd /data/rabbitmq/ssl [root@ecs ssl]# openssl req -x509 -newkey rsa:4096 -days 3650 -nodes \ -keyout ca.key -out ca.crt \ -subj "/C=CN/ST=Jiangsu/L=Nanjing/O=Maisi/OU=R&D/CN=RabbitMQ"生成服务端私钥和证书请求
[root@ecs ssl]# openssl req -newkey rsa:4096 -nodes \ -keyout server.key -out server.csr \ -subj "/C=CN/ST=Jiangsu/L=Nanjing/O=Maisi/OU=R&D/CN=RabbitMQ"创建SAN(Subject Alternative Name,主题备用名称)扩展文件
[root@ecs ssl]# cat > v3.ext <<EOF subjectAltName = @alt_names [alt_names] DNS.1 = rabbitmq.local DNS.2 = localhost IP.1 = 192.168.1.3 IP.2 = 127.0.0.1 EOF注:需要将192.168.1.3替换RabbitMQ真实的公网/内网地址。
使用CA签发服务端证书
[root@ecs ssl]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 3650 -extfile v3.ext
运行rabbitmq容器
[root@ecs ~]# cat > /data/rabbitmq/rabbitmq.conf <<EOF
default_vhost = /
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/ssl/ca.crt
ssl_options.certfile = /etc/rabbitmq/ssl/server.crt
ssl_options.keyfile = /etc/rabbitmq/ssl/server.key
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
management.tcp.port = 15672
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/ssl/ca.crt
management.ssl.certfile = /etc/rabbitmq/ssl/server.crt
management.ssl.keyfile = /etc/rabbitmq/ssl/server.key
EOF
[root@ecs ~]# docker run --name=rabbitmq \
-p 5671-5672:5671-5672 \
-p 15671-15672:15671-15672 \
-e RABBITMQ_DEFAULT_USER=root \
-e RABBITMQ_DEFAULT_PASS=root \
--hostname rabbitmq \
-v /data/rabbitmq:/var/lib/rabbitmq \
-v /data/rabbitmq/ssl:/etc/rabbitmq/ssl/ \
-v /data/rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro \
-d registry.cn-shanghai.aliyuncs.com/maisi/rabbitmq:4.2.2--hostname是为了固定RabbitMQ的节点名称,从而保证数据的持久化。不指定--hostname,Docker创建容器时,会以容器ID作为主机名。RabbitMQ的数据(队列、交换机、用户、Vhost)保存在/var/lib/rabbitmq/mnesia/rabbit@[主机名]下,即使-v /data/rabbitmq:/var/lib/rabbitmq也会因为机器名不一致而无法直接使用之前的容器数据。
不指定RABBITMQ_DEFAULT_USER,rabbitmq默认会创建guest用户,并设置密码为guest。
常用端口说明:
| 端口 | 协议 | 说明 |
|---|---|---|
| 5672 | AMQP | 客户端连接端口 应用程序(java、node等)与RabbitMQ进行消息收发通信的端口 |
| 5671 | AMQP(TLS/SSL) | 客户端加密传输连接端口 |
| 15672 | HTTP | Web管理端口 |
| 15671 | HTTP(TLS/SSL) | Web加密传输管理端口 |
| 1883 | MQTT | 客户端连接端口 |
| 15675 | MQTT | 客户端WebSocket传输连接端口 |
| 4369 | EPMD Erlang Port Mapper Daemon | Erlang节点发现端口 |
| 25672 | Erlang Distribution | 节点间通信与CLI端口 |
| 15692 | Prometheus Metrics | Prometheus监控端口 |
防火墙开放端口
[root@ecs ~]# firewall-cmd --zone=public --add-port=5671-5672/tcp --permanent
[root@ecs ~]# firewall-cmd --zone=public --add-port=15671-15672/tcp --permanent
[root@ecs ~]# firewall-cmd --zone=public --add-port={1883,15675}/tcp --permanent
[root@ecs ~]# firewall-cmd --reload命令行操作
插件管理
开启Web管理
[root@ecs ~]# docker exec -it rabbitmq /bin/bash root@20104fa324e1:/# rabbitmq-plugins enable rabbitmq_management查看RabbitMQ监听的所有端口:
root@20104fa324e1:/# rabbitmq-diagnostics listeners Asking node rabbit@rabbitmq to report its protocol listeners ... Interface: [::], port: 15692, protocol: http/prometheus, purpose: Prometheus exporter API over HTTP Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0 Interface: [::], port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS Interface: [::], port: 15671, protocol: https, purpose: HTTP API over TLS (HTTPS)Web管理地址:
开启延时消息插件
rabbitmq 4.2.2
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v4.2.0/rabbitmq_delayed_message_exchange-4.2.0.ez [root@ecs src]# docker cp ./rabbitmq_delayed_message_exchange-4.2.0.ez rabbitmq:/plugins Successfully copied 44.5kB to rabbitmq:/opt/rabbitmq/plugins [root@ecs src]# docker exec -it rabbitmq /bin/bash root@20104fa324e1:/# rabbitmq-plugins enable rabbitmq_delayed_message_exchange Enabling plugins on node rabbit@20104fa324e1: rabbitmq_delayed_message_exchange The following plugins have been configured: rabbitmq_delayed_message_exchange rabbitmq_management rabbitmq_management_agent rabbitmq_prometheus rabbitmq_web_dispatch Applying plugin configuration to rabbit@20104fa324e1... The following plugins have been enabled: rabbitmq_delayed_message_exchange started 1 plugins.rabbitmq 4.0.4
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v4.0.7/rabbitmq_delayed_message_exchange-v4.0.7.ez注:
- rabbitmq_delayed_message_exchange和rabbitmq的主次版本号(x.y.z的x.y)必须一致,否则会无法兼容。例如:
rabbitmq_delayed_message_exchange-4.2.0.ez可以用于rabbitmq:4.2.2,但不用用于rabbitmq:4.0.4。 - 开启延时消息插件后,必须重启rabbitmq容器才能生效。
- rabbitmq_delayed_message_exchange和rabbitmq的主次版本号(x.y.z的x.y)必须一致,否则会无法兼容。例如:
开启MQTT插件
root@20104fa324e1:/# rabbitmq-plugins enable rabbitmq_web_mqtt开启rabbitmq_web_mqtt会自动开启rabbitmq_mqtt。mqtt连接参数示例值:
ws mqtt Name mqtt mqtt Host ws://192.168.1.54 mqtt://192.168.1.54 Port 15675 1883 Path /ws Username root root Password dcIvMA3EHignTxAV dcIvMA3EHignTxAV
用户管理
添加用户
root@20104fa324e1:/# rabbitmqctl add_user maisi mM1lO8nN2sO4eK8q修改用户密码
root@20104fa324e1:/# rabbitmqctl change_password maisi mM1lO8nN2sO4eK8q设置用户角色
root@20104fa324e1:/# rabbitmqctl set_user_tags maisi administrator设置administrator后即可登录Web Management UI。
删除指定用户
root@20104fa324e1:/# rabbitmqctl delete_user maisi查看所有用户
root@20104fa324e1:/# rabbitmqctl list_users
vhost管理
添加vhost
root@20104fa324e1:/# rabbitmqctl add_vhost maisi注:
maisi和/maisi是2个不同的vhost,vhost名称允许有/路径符号。设置用户权限
用户maisi在虚拟主机maisi下拥有Configure、Write和Read任意资源的权限。
root@20104fa324e1:/# rabbitmqctl set_permissions -p maisi maisi ".*" ".*" ".*"-p:指定vhost。".*" ".*" ".*":.*是正则表达式,表示任意字符。分别对应Configure(配置任意名称的Exchange和Queue)、Write(给任意名称的Exchange或Queue发送消息)和Read(从任意名称的Queue读取消息)。
查看所有vhost
root@20104fa324e1:/# rabbitmqctl list_vhosts删除指定vhost
root@20104fa324e1:/# rabbitmqctl delete_vhost maisi
队列管理
查看队列列表
root@20104fa324e1:/# rabbitmqctl list_queues -p maisi删除指定队列
root@20104fa324e1:/# rabbitmqctl delete_queue default-delay -p maisi
客户端调用
Node.JS
const amqp = require('amqplib');
const fs = require('fs');
const path = require('path');
(async () => {
const username = 'maisi';
const password = 'mM1lO8nN2sO4eK8q';
const host = '192.168.1.3';
const port = 5672;
const vhost = 'maisi';
try {
/*
const connection = await amqp.connect(`amqp://${username}:${password}@${host}:${port}/${vhost}?heartbeat=60&frameMax=8192`);
*/
const connection = await amqp.connect({
protocol: 'amqps',
hostname: host,
port: 5671,
username,
password,
vhost,
heartbeat: 60,
frameMax: 8192
}, {
//报错:Error: self-signed certificate in certificate chain
//方法一:忽略自签名证书校验
rejectUnauthorized: false,
//方法二:添加CA
rejectUnauthorized: true,
ca: [fs.readFileSync(path.join(__dirname, 'ca.crt'))]
});
console.log({ connection });
} catch (e) {
console.log(e);
}
})();注:RabbitMQ从4.1.0开始,RabbitMQ官方为了提高性能和安全性,将AMQP协议中frame_max(最大帧大小)的最小允许值从4096字节提升到了8192字节。如果amqplib版本较旧,连接RabbitMQ时最大帧大小默认使用的是4096,不符合新版RabbitMQ的最低要求,RabbitMQ就会拒绝连接,并抛出异常:failed to negotiate connection parameters: negotiated frame_max = 4096 is lower than the minimum allowed value (8192)。
解决方法(任选其一):
- 升级amqplib到最新版(当前:2.0.1);
修改连接参数,添加
frameMax=8192:const url = `amqp://${username}:${password}@${hostname}:${port}/${vhost}?heartbeat=60&frameMax=8192`;
Python
import pika
host = '192.168.1.3'
port = 5672
username = 'maisi'
password = 'mM1lO8nN2sO4eK8q'
vhost = 'maisi'
try:
credentials = pika.PlainCredentials(username, password)
# connection = pika.BlockingConnection(pika.ConnectionParameters(host, port, vhost, credentials))
connection = pika.BlockingConnection(pika.ConnectionParameters(
host=host,
port=port,
virtual_host=vhost,
credentials=credentials
))
channel = connection.channel()
print(channel)
except Exception as e:
print(e)
finally:
if 'connection' in locals() and connection.is_open:
connection.close() Node.js安装及npm、yarn配置
安装Node.js
下载地址:https://nodejs.org/download/release/
[root@ecs ~]# yum install -y wget
[root@ecs ~]# cd /usr/local/src
[root@ecs src]# wget https://nodejs.org/download/release/v22.23.1/node-v22.23.1-linux-x64.tar.xz
[root@ecs src]# tar -Jxvf node-v22.23.1-linux-x64.tar.xz
[root@ecs src]# mv node-v22.23.1-linux-x64 /usr/local/node
[root@ecs src]# echo "export PATH=\$PATH:/usr/local/node/bin/" >> /etc/profile
[root@ecs src]# source /etc/profile
[root@ecs src]# node --version
v22.9.0
[root@ecs src]# npm --version
10.8.3Node.js从v18开始,CentOS 7.9默认glibc的版本低于Node.js动态链接库依赖的glibc版本,因此必须升级glibc版本。
Node.js v18+要求glibc的版本不能低于2.28,升级教程参考:CentOS 7.9升级glibc到2.28-2.33。
| 动态链接库 | 系统默认支持最高版本符号 | node v18+依赖glibc最低版本符号 |
|---|---|---|
| /lib64/libm.so.6 | GLIBC_2.15 | GLIBC_2.27 |
| /lib64/libstdc++.so.6 | GLIBCXX_3.4.19 CXXABI_1.3.7 | GLIBCXX_3.4.21 CXXABI_1.3.9 |
| /lib64/libc.so.6 | GLIBC_2.17 | GLIBC_2.28 |
查看node依赖的动态链接库
[root@ecs ~]# cd /usr/local/node/bin
[root@ecs bin]# ldd node
./node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./node)
./node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./node)
./node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by ./node)
./node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by ./node)
./node: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by ./node)
./node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by ./node)
./node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by ./node)
linux-vdso.so.1 => (0x00007ffd8d1f4000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f46a0408000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f46a0100000)
libm.so.6 => /lib64/libm.so.6 (0x00007f469fdfe000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f469fbe8000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f469f9cc000)
libc.so.6 => /lib64/libc.so.6 (0x00007f469f5fe000)
/lib64/ld-linux-x86-64.so.2 (0x00007f46a060c000)查看版本符号信息
[root@ecs ~]# strings /lib64/libm.so.6 | grep GLIBC
GLIBC_2.2.5
GLIBC_2.4
GLIBC_2.15
GLIBC_PRIVATE
GLIBC_2.15
__strtold_nan@@GLIBC_PRIVATE
__errno_location@@GLIBC_2.2.5
errno@@GLIBC_PRIVATE
qsort@@GLIBC_2.2.5
__strtod_nan@@GLIBC_PRIVATE
fputs@@GLIBC_2.2.5
memset@@GLIBC_2.2.5
feupdateenv@@GLIBC_2.2.5
GLIBC_2.4
_rtld_global_ro@@GLIBC_PRIVATE
__strtof_nan@@GLIBC_PRIVATE
memmove@@GLIBC_2.2.5
fwrite@@GLIBC_2.2.5
__cxa_finalize@@GLIBC_2.2.5
stderr@@GLIBC_2.2.5查看依赖库版本
[root@ecs ~]# ll /lib64/libc.so.6
lrwxrwxrwx. 1 root root 12 Jun 27 17:06 /lib64/libc.so.6 -> libc-2.17.solibc-2.17.so表示libc的版本是2.17。
安装yarn
yarn由Facebook和Google等公司联合推出的js包管理工具。yarn可以同步安装所有package,且遇到已经安装过的包会从本地缓存获取。为了防止拉取模块时出现版本兼容问题,yarn.lock会记录安装的模块版本号,这样就可以确保每次拉取项目依赖时模块的版本都是一致的。
[root@ecs ~]# npm -g install yarn --registry=https://registry.npmmirror.com配置阿里云镜像源
[root@ecs ~]# yarn config set registry https://registry.npmmirror.com
[root@ecs ~]# yarn config get registry打开power shell,执行以下策略,即可在vscode终端执行yarn。
PS C:\Users\Administrator> set-executionpolicy remotesigned缓存操作
| 指令 | 说明 |
|---|---|
yarn cache dir | 查看缓存目录 Linux: /usr/local/share/.cache/yarn/v6Windows: C:\Users\Administrator\AppData\Local\Yarn\Cache\v6 |
yarn cache list | 查看包缓存列表 |
yarn cache clean | 清空缓存,生产服务器无需yarn缓存,在安装好项目依赖后,可以清空缓存以释放更多的磁盘空间。 |
开源站点流量统计分析工具umami安装部署指南
Umami是一款开源、注重隐私的网络分析工具,可作为谷歌分析的替代方案。它能提供有关网站流量、用户行为和性能的重要见解,同时始终将数据隐私放在首位。不收集或存储个人数据,无需使用Cookie,并且符合GDPR(General Data Protection Regulation,通用数据保护条例)和PECR(Privacy and Electronic Communications Regulations,隐私与电子通信条例)标准。
Github:https://github.com/umami-software/umami
官网网址:https://umami.is/
Docker部署umami
手动部署
运行postgres
[root@ecs ~]# docker run --name umami-db \ --privileged=true \ -e POSTGRES_DB=umami_db \ -e POSTGRES_USER=umami \ -e POSTGRES_PASSWORD=Ri71kHISuS9mDVBF \ -p 5432:5432 \ -v /data/umami/data:/var/lib/postgresql/data \ -d postgres:16.13-alpine编译docker镜像(非必须,可以直接使用官方docker镜像)
[root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://tvv.tw/https://github.com/umami-software/umami/archive/refs/tags/v3.2.0.tar.gz [root@ecs src]# tar -zxvf v3.2.0.tar.gz [root@ecs src]# cd umami-3.2.0 [root@ecs umami-3.2.0]# sed -i '/ARG NODE_IMAGE_VERSION/s/^/# /; /ARG NODE_IMAGE_VERSION/a\ARG NODE_IMAGE_VERSION="22-bookworm-slim"' Dockerfile [root@ecs umami-3.2.0]# sed -i '/apk add/d' Dockerfile [root@ecs umami-3.2.0]# sed -i '/npm install -g pnpm/s#$# \&\& pnpm config set registry https://registry.npmmirror.com#' Dockerfile [root@ecs umami-3.2.0]# sed -i 's#https://#https://tvv.tw/https://#g' scripts/build-geo.js [root@ecs umami-3.2.0]# sed -i -e '/ARG BASE_PATH/a\ARG SKIP_BUILD_GEO' -e '/ENV DATABASE_URL/a\ENV SKIP_BUILD_GEO=\${SKIP_BUILD_GEO:-0}' Dockerfile [root@ecs umami-3.2.0]# docker build \ --progress=plain \ --no-cache \ --build-arg SKIP_BUILD_GEO=1 \ --build-arg NODE_IMAGE_VERSION=22-bookworm-slim \ -t umami .说明:
/ARG NODE_IMAGE_VERSION/:查找ARG NODE_IMAGE_VERSION所在行;s/^/# /:在行开头添加#;;:执行下一个命令;/ARG NODE_IMAGE_VERSION/a:在ARG NODE_IMAGE_VERSION下一行追加内容。
运行umami
[root@ecs ~]# wget https://tvv.tw/https://raw.githubusercontent.com/GitSquared/node-geolite2-redist/master/redist/GeoLite2-City.tar.gz -P /usr/local/src/ [root@ecs ~]# mkdir -p /data/umami/{geo,data} [root@ecs ~]# tar -zxvf /usr/local/src/GeoLite2-City.tar.gz -C /usr/local/src/ [root@ecs ~]# mv /usr/local/src/GeoLite2-City_20260703/GeoLite2-City.mmdb /data/umami/geo/ [root@ecs ~]# docker run --name umami \ --restart=always \ -p 3000:3000 \ -e DATABASE_URL=postgresql://umami:Ri71kHISuS9mDVBF@db:5432/umami_db \ -e DATABASE_TYPE=postgresql \ -e APP_SECRET=$(openssl rand -hex 8) \ --link umami-db:db \ -v /data/umami/geo/GeoLite2-City.mmdb:/app/geo/GeoLite2-City.mmdb:ro \ -d docker.umami.is/umami-software/umami:postgresql-latest访问地址:
http://47.101.38.23:3000/,初始用户名:admin,密码:umami。nginx反向代理设置
{ location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; # WebSocket支持 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; # 将客户端原始请求协议(HTTP/HTTPS)传递给Next.js proxy_set_header X-Forwarded-Proto $scheme; # 将客户端真实请求域名传递给Next.js(解决Origin不匹配) proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; } }
自动部署
编写docker-compose.yaml
postgres版
version: '3' services: umami: image: ghcr.nju.edu.cn/umami-software/umami:postgresql-latest ports: - "3000:3000" environment: DATABASE_URL: postgresql://umami:Ri71kHISuS9mDVBF@db:5432/umami_db DATABASE_TYPE: postgresql APP_SECRET: fVBjK4ZA5LUDZgFB volumes: - /data/umami/geo/GeoLite2-City.mmdb:/app/geo/GeoLite2-City.mmdb:ro depends_on: - db restart: always db: image: postgres:16.13-alpine environment: POSTGRES_DB: umami_db POSTGRES_USER: umami POSTGRES_PASSWORD: Ri71kHISuS9mDVBF volumes: - /data/umami/data:/var/lib/postgresql/data restart: alwaysmysql版
version: '3' services: umami: image: docker.umami.is/umami-software/umami:mysql-latest ports: - "3000:3000" environment: DATABASE_URL: mysql://umami:Ri71kHISuS9mDVBF@db:3306/umami_db DATABASE_TYPE: mysql APP_SECRET: fVBjK4ZA5LUDZgFB volumes: - /data/umami/geo/GeoLite2-City.mmdb:/app/geo/GeoLite2-City.mmdb:ro depends_on: - db restart: always db: image: mysql:8.0 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: Ri71kHISuS9mDVBF MYSQL_DATABASE: umami_db MYSQL_USER: umami MYSQL_PASSWORD: Ri71kHISuS9mDVBF volumes: - /data/umami/data:/var/lib/mysql - /data/umami/log:/var/log/mysql restart: always注:umami 2.x使用mysql数据库,mysql仅支持8.0及以上版本。目前(截止到2026年7月8日)官网的umami:mysql-latest的版本为2.20.2,而官网的umami:postgresql-latest最新版本为3.2.0,最新版本性能更佳,推荐使用postgres的umami。
如果需要使用1.x版本,可以使用:
ghcr.io/mikecao/umami:mysql-latest(1.33.2),Github:https://github.com/mikecao/umami/pkgs/container/umami/versions。version: '3' services: umami: image: ghcr.nju.edu.cn/mikecao/umami:mysql-latest ports: - "3000:3000" environment: DATABASE_URL: mysql://umami:Ri71kHISuS9mDVBF@db:3306/umami_db DATABASE_TYPE: mysql HASH_SALT: fVBjK4ZA5LUDZgFB volumes: - /data/umami/geo/GeoLite2-City.mmdb:/app/public/geo/GeoLite2-Country.mmdb:ro depends_on: - db restart: always db: image: mysql:5.7 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: Ri71kHISuS9mDVBF MYSQL_DATABASE: umami_db MYSQL_USER: umami MYSQL_PASSWORD: Ri71kHISuS9mDVBF volumes: - /data/umami/data:/var/lib/mysql - /data/umami/log:/var/log/mysql restart: always运行
[root@ecs umami]# docker compose up -d
Node.js部署umami
源码编译
[root@ecs ~]# npm -g install pnpm --registry=https://registry.npmmirror.com [root@ecs ~]# pnpm config set registry https://registry.npmmirror.com [root@ecs ~]# cd /usr/local/src [root@ecs src]# wget https://tvv.tw/https://github.com/umami-software/umami/archive/refs/tags/v3.2.0.tar.gz [root@ecs src]# tar -zxvf v3.2.0.tar.gz [root@ecs src]# mv umami-3.2.0 /data/umami-3.2.0 [root@ecs src]# cd /data/umami-3.2.0 [root@ecs umami-3.2.0]# pnpm install [root@ecs umami-3.2.0]# cat > .env << EOF DATABASE_URL=postgresql://umami:Ri71kHISuS9mDVBF@192.168.1.3:5432/umami_db EOF [root@ecs umami-3.2.0]# export SKIP_BUILD_GEO=1 [root@ecs umami-3.2.0]# pnpm build [root@ecs umami-3.2.0]# pnpm start注:必须先
pnpm build编译生成生产环境代码(生成到.next目录)才能pnpm start。使用pm2管理进程
[root@ecs src]# npm -g install pm2 --registry=https://registry.npmmirror.com [root@ecs src]# pm2 start pnpm --name umami -- start [root@ecs src]# pm2 startup [root@ecs src]# pm2 savepm2其它启动方式:
pm2 start "pnpm start" --name umamipm2 start npx --name "umami" -- next start -p 3000 -H 0.0.0.0pm2 start npm --name "umami" -- start
说明:
pm2 start pnpm --name umami -- start最后的--是参数分隔符,表示属于pm2的参数到此为止,--后面所有的内容都传递给启动脚本或程序(pnpm);pm2 startup设置开机自启动pm2,可以使用pm2 unstartup systemd取消开机自启动;- 设置了开机自启动后,必须使用
pm2 save生成进程快照,当服务器重启后,pm2可以根据进程快照重新拉起所有业务程序。
修改项目端口
umami默认监听3000端口,可以使用以下方法将umami运行在其它端口:
启动命令中指定端口号
[root@ecs src]# npx next start -p 3000pm2启动进程使用:
[root@ecs src]# pm2 start npx --name umami -- next start -p 3000 -H 0.0.0.0start-env脚本调用环境变量
[root@ecs src]# sed -i "2s/next-start/next-start.js/" /data/umami-3.2.0/scripts/start-env.js [root@ecs src]# HOSTNAME=0.0.0.0 && pnpm start-envpm2启动进程使用:
[root@ecs src]# pm2 start "HOSTNAME=0.0.0.0 && pnpm start-env" --name umami分析
/data/umami-3.2.0/scripts/start-env.js源码:import 'dotenv/config'; import cli from 'next/dist/cli/next-start'; cli.nextStart({ port: process.env.PORT || 3000, hostname: process.env.HOSTNAME || '0.0.0.0', });注:
- 必须给
next/dist/cli/next-start添加.js后缀,否则会找不到引入文件; - PORT可以直接在.env中指定,但是HOSTNAME必须在命令行中指定。CentOS 7.9默认在/etc/profile设置了HOSTNAME的值为当前机器名,dotenv默认保护机制不允许.env中设置的环境变量覆盖process.env中已存在的值,因此在.env中设置HOSTNAME将无效,而如果HOSTNAME使用机器名,将无法进行外网访问。
- 必须给
使用
事件跟踪
css调用
要启用事件跟踪,只需给跟踪的元素添加一个特殊的css类。
示例:
umami 2.x/3.x:
<button id="signup" class="button" data-umami-event="signup" data-umami-event-foo="bar">Sign up</button>umami 1.x:
<button id="signup" class="button umami--click--signup">Sign up</button>当用户点击按钮时,Umami将记录一个名为
signup的事件,事件类型为click。注:umami 1.x的事件类型仅支持click,即类的有效值必须是
umami--click--<事件名称>。javascript调用
示例:
umami 2.x/3.x:
const button = document.getElementById('signup'); button.onclick = () => umami.track('signup', {foo: 'bar'});umami 1.x:
const button = document.getElementById('signup'); button.onclick = () => umami('signup');当用户点击按钮时,Umami将记录一个名为
signup的事件,事件类型为custom。注:umami 1.x不支持事件数据,即
umami('事件名', {})这样的调用方式是无效的。
Beyond Compare 3 “许可证密钥已被撤销”解决方法
备份设置
打开Beyond Compare 3,在主界面工具栏依次点击:工具->导出设置,将当前设置备份一份;
删除授权
Windows 7及以上操作系统,打开目录:
C:\Users\Administrator\AppData\Roaming\Scooter Software\Beyond Compare 3\,Windows XP打开目录:
C:\Documents and Settings\Administrator\Application Data\Scooter Software\Beyond Compare 3\。删除目录内的所有文件;
macOS删除文件:
/Users/$(whoami)/Library/Application Support/Beyond Compare/registry.dat。注:macOS仅需删除
registry.dat即可,无需重新授权。重新授权
重新打开Beyond Compare 3,自动进入初始化向导,在
导入设置页面导入第1步备份的设置文件。进入主界面后,在工具栏依次点击:帮助->输入密钥,复制以下密钥粘贴到输入框:
--- BEGIN LICENSE KEY --- mv1nPlXAywBDCdhxFc9QOVv6TBcQHLAXBQUAKTh3ie4fqSEOnWrPsnVkF yt0wAkJHweoExRJWWVwwCniKNROSdJzJXE6YVapYW7f+tRRXRFI4yn4Nj jZ0RiiqGRCTVzwComUcXB-eiFWRBY6JpSsCNkmIxL5KsRCo442djHhTZE --- END LICENSE KEY -----勾选“注册到所有用户”后点击“确认”退出即可。