Apache Vysper 常用 CLI 命令与工具详解
Apache Vysper 0.7 常用 CLI 命令与工具详解:run.sh 启动停止、JVM 参数注入、jps/jstack 观测、日志与 stanza 报文、openssl 探测、XEP-0133 管理命令与非 Spring 内存运行时实测
Apache Vysper 常用 CLI 命令与工具详解
目标:把管理一台 Apache Vysper 0.7 服务器所需的全部命令行操作讲透——启动、停止、观测、日志、协议探测、在线管理命令,以及一个鲜为人知的非 Spring 内存运行时。所有命令与回显均在 Ubuntu 22.04 服务器实测。
一、bin/ 目录与 run.sh 启动脚本
发行包的命令行入口只有两个文件(实测 ls bin/):
run.bat
run.sh
setenv.sh
run.bat 是 Windows 等价物,Linux 上唯一入口是 run.sh。它是个经典的类 Unix 启动包装脚本,干三件事(关键行摘自实际文件):
[ -f "$BASEDIR"/bin/setenv.sh ] && . "$BASEDIR"/bin/setenv.sh
CLASSPATH=$CLASSPATH_PREFIX:"$BASEDIR"/config:"$REPO"/nbxml-0.7.jar:"$REPO"/vysper-core-0.7.jar:...
EXTRA_JVM_ARGUMENTS=""
exec "$JAVACMD" $JAVA_OPTS \
$EXTRA_JVM_ARGUMENTS \
-classpath "$CLASSPATH" \
-Dapp.name="run.sh" \
-Dapp.pid="$$" \
-Dapp.repo="$REPO" \
-Dbasedir="$BASEDIR" \
org.apache.vysper.spring.ServerMain \
"$@"
逐项解读:
| 环节 | 说明 |
|---|---|
setenv.sh | 存在则 source,是配置 JAVA_HOME/JAVA_OPTS 的正规入口(默认发行包不带,需自建) |
CLASSPATH | 逐个列出 lib/ 下 50 余个 jar + config/ 目录;没有用 lib/* 通配 |
CLASSPATH_PREFIX | 用户可注入的前缀 classpath——挂自研模块 jar 就写它 |
EXTRA_JVM_ARGUMENTS | 用户可注入的额外 JVM 参数,同样写在 setenv.sh |
org.apache.vysper.spring.ServerMain | 真正的启动类:读 classpath:spring-config.xml 完成装配 |
$@ | 位置参数原样传给 main,0.7 的 ServerMain 并不解析任何启动参数 |
注意两个坑:run.sh 里 REPO 默认是 $BASEDIR/lib,所以启动目录无关紧要,但 config/ 与 log/ 的相对路径解析基于 $BASEDIR(由脚本自身位置决定),移动目录不影响;-Dapp.pid=$$ 记录了 shell 的 PID——exec 之后就是 java 进程的 PID,可用它做进程定位。
二、启动与停止
2.1 前台启动(调试用)
cd /opt/vysper/vysper-0.7
bin/run.sh
控制台实时输出启动日志,从 Spring 上下文刷新到模块逐个加载:
07:21:10,309 | INFO | org.springframework.context.support.ClassPathXmlApplicationContext | Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@76c0fd31: startup date [Fri Oct 16 07:21:10 GMT 2026]; root of context hierarchy
07:21:10,331 | INFO | org.springframework.beans.factory.xml.XmlBeanDefinitionReader | Loading XML bean definitions from class path resource [spring-config.xml]
Ctrl+C 即退出。前台方式便于看报错,生产不用。
2.2 后台启动(生产方式)
cd /opt/vysper/vysper-0.7
nohup bin/run.sh > /root/vysper-opt.log 2>&1 &
sleep 12
ps -ef | grep [S]erverMain | cut -c1-120
ss -tlnp | grep 5222
实测输出:
root 4018 1 0 07:05 ? 00:00:05 /opt/jdk/jdk8u504-b01/bin/java -Xms256m -Xmx256m -classpath :/opt/vysper/vysper-0.7/conf ...
LISTEN 0 50 *:5222 *:* users:(("java",pid=4018,fd=107))
💡 技术拓展:
ss的users:(("java",pid=4018,fd=107))直接把端口和进程对上了,这是确认"5222 到底是哪个实例在听"的最快方式。若启用了 BOSH,还应看到 8080。
2.3 停止与重启
Vysper 没有提供停止命令或管理接口,停止就是 kill 进程:
# 停止单实例(推荐,按 PID)
kill $(ps -ef | awk '/[S]erverMain/{print $2}' | head -1)
# 确认干净
ps -ef | grep [S]erverMain | wc -l
实测输出:
0
重启即先 kill 再 nohup,两步合起来的标准组合:
kill $(ps -ef | awk '/[S]erverMain/{print $2}') 2>/dev/null; sleep 3
cd /opt/vysper/vysper-0.7 && nohup bin/run.sh > /root/vysper-opt.log 2>&1 &
sleep 12 && ss -tlnp | grep 5222
kill 默认发 SIGTERM,JVM 正常退出,日志文件不会截断(log4j 的 Append=true),重启后继续追加。
⚠️ 一个实测出来的坑:端口占用时进程会变"僵尸"。 旧实例还监听 5222 时启动新实例,MINA 绑定失败抛异常,但主进程不会退出:
Caused by: org.apache.mina.core.RuntimeIoException: Failed to bind
at org.apache.vysper.mina.TCPEndpoint.start(TCPEndpoint.java:...)
此时 ps -ef | grep ServerMain 能看到两个实例,端口仍归旧实例。处置:全部 kill 干净再启动。改配置前先停服务,是避免这个坑的最省事习惯。
三、JVM 观测工具
3.1 jps:确认进程与参数
/opt/jdk/jdk8u504-b01/bin/jps -lv | grep ServerMain
实测输出:
4018 ServerMain -Xms256m -Xmx256m -Dapp.name=run.sh -Dapp.pid=4018 -Dapp.repo=/opt/vysper/vysper-0.7/lib -Dbasedir=/opt/vysper/vysper-0.7
-lv 把 setenv.sh 注入的 -Xms256m -Xmx256m 展示出来,用于验证 JVM 参数是否真的生效(比翻日志可靠)。
3.2 jstack:线程快照
PID=$(ps -ef | awk '/[S]erverMain/{print $2}' | head -1)
/opt/jdk/jdk8u504-b01/bin/jstack $PID | grep -cE '^"'
/opt/jdk/jdk8u504-b01/bin/jstack $PID | grep -E '^"' | head -8
实测输出(启用 BOSH 的实例):
33
"Attach Listener" #22 daemon prio=9 os_prio=0 tid=0x000071ca94001000 nid=0x1567 waiting on condition [0x0000000000000000]
"DestroyJavaVM" #21 prio=5 os_prio=0 tid=0x000071cae400b000 nid=0x1512 waiting on condition [0x0000000000000000]
"HashSessionScavenger-0" #20 daemon prio=5 os_prio=0 tid=0x000071cae49ca000 nid=0x1531 in Object.wait() [0x000071cabedfe000]
"qtp728885526-19" #19 prio=5 os_prio=0 tid=0x000071cae49a9800 nid=0x1530 waiting on condition [0x000071cabeefe000]
"qtp728885526-18" #18 prio=5 os_prio=0 tid=0x000071cae49a7800 nid=0x152f waiting on condition [0x000071cabeffe000]
...
33 个线程里 qtp*(Jetty 线程池)与 HashSessionScavenger 来自 BOSH 模块内嵌的 Jetty 7——即使 BOSH 零连接,这些线程也存在;排查 CPU/内存问题时可据此区分 TCP 通道与 HTTP 通道的线程组。
3.3 jmap:实测失败路径
/opt/jdk/jdk8u504-b01/bin/jmap -heap $PID
实测输出(本机默认权限下失败):
Attaching to process ID 5389, please wait...
ERROR: ptrace(PTRACE_ATTACH, ..) failed for 5389: Operation not permitted
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 5389: Operation not permitted
jmap -heap 依赖 ptrace 系统调用,缺 CAP_SYS_PTRACE 能力(或内核 ptrace_scope 收紧)时会这样报错。处置:以 root 且 ptrace_scope=0 的常规服务器上可正常运行;受限环境下放弃 jmap,改用 3.1 的 jps 验证参数、3.2 的 jstack 看线程即可覆盖日常运维需求。同一环境下 jstack 能正常 attach,说明故障面只在 jmap 的 ptrace 依赖上。
四、日志工具
4.1 两个日志文件
cd /opt/vysper/vysper-0.7 && ls -l log/
实测输出:
-rw-r--r-- 1 root root 26411 Oct 16 07:25 stanza.log
-rw-r--r-- 1 root root 138884 Oct 16 07:25 vysper_server.log
| 文件 | 内容 | 用途 |
|---|---|---|
vysper_server.log | 服务器运行日志(模块加载、认证、路由异常) | 服务排障 |
stanza.log | 逐条 XMPP 报文摘要(方向+类型+关键参数) | 协议排障 |
两者按 config/log4j.xml 滚动:500KB 上限、保留 1 份备份(*.log.1)。长期运行需外接 logrotate 或调大 MaxFileSize。
4.2 实时盯报文:tail + stanza.log
tail -f /opt/vysper/vysper-0.7/log/stanza.log
发起一次登录与发消息后,实测滚动出:
INFO 07:25:58,263 | client | iq.id='d1'.to='vysper.org'.type='get'.query.disco.info
INFO 07:25:58,264 | server | iq.id='d1'.from='vysper.org'.type='result'.query.disco.info.feature='http://jabber.org/protocol/disco#info'.feature='jabber:iq:version'.feature='urn:xmpp:time'.feature='vcard-temp'.feature='urn:xmpp:ping'
INFO 07:25:58,265 | client | message.body.hello from user1 at 2026-10-16 07:25:58
INFO 07:25:58,267 | server | message.body.hello from user1 at 2026-10-16 07:25:58
INFO 07:25:58,304 | client | message.body.reply from user2
INFO 07:25:58,305 | server | message.body.reply from user2
client 是客户端发来的 stanza,server 是服务器回出的 stanza,一问一答成对出现。客户端"没收到消息"这类问题,先看这里能立刻区分是"没收到报文"还是"报文内容异常"。
4.3 控制台降噪:Threshold 调整
config/log4j.xml 中 CONS appender 的 Threshold 默认 TRACE,控制台很吵。改成 WARN 后重启:
sed -i '0,/<param name="Threshold" value="TRACE"\/>/s//<param name="Threshold" value="WARN"\/>/' config/log4j.xml
kill $(ps -ef | awk '/[S]erverMain/{print $2}') 2>/dev/null; sleep 3
cd /opt/vysper/vysper-0.7 && nohup bin/run.sh > /root/vysper-log4j-warn.log 2>&1 &
sleep 12
wc -l < /root/vysper-log4j-warn.log
实测输出:
5
同窗口 TRACE 阈值下控制台 60 余行、WARN 阈值下 5 行。只改 CONS 不影响 log/ 下两个文件,排障期记得改回 TRACE。
五、TLS 探测:openssl s_client
不带任何客户端就摸清服务端 TLS 状况,s_client -starttls xmpp 是最趁手的工具。
看流头与证书信任判定(默认安全级别,0.7 自带的 2005 年 511 位 MD5 证书会被直接拒绝):
echo | openssl s_client -starttls xmpp -connect 127.0.0.1:5222 2>&1 | sed -n '1,3p'
实测输出:
CONNECTION ESTABLISHED
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
查看完整校验结果需放宽安全级别后落地证书:
echo | openssl s_client -starttls xmpp -connect 127.0.0.1:5222 -cipher 'ALL:@SECLEVEL=0' 2>&1 | grep -E "subject=|Verification|New, "
实测输出:
subject=CN=montague.im, O=Assumed Security, OU=Functional Testing, C=US
Verification error: self-signed certificate
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
(CN=montague.im 是 2005 年生成 bogus 证书时留下的名字,这就是"罗密欧与朱丽叶"测试证书。)换上 2048 位新证书后(换法见《Apache Vysper 配置参数详解》第六节)无需任何放宽参数:
echo | openssl s_client -starttls xmpp -connect 127.0.0.1:5222 -servername vysper.org 2>/dev/null | grep -E "New, |Verification"
echo | openssl s_client -starttls xmpp -connect 127.0.0.1:5222 -servername vysper.org 2>/dev/null | openssl x509 -noout -subject -dates
实测输出:
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Verification error: self-signed certificate
subject=CN=vysper.org, OU=Demo, O=Demo, L=Beijing, C=CN
notBefore=Oct 16 07:04:02 2026 GMT
notAfter=Oct 13 07:04:02 2036 GMT
Verification error: self-signed certificate 是自签证书的固有提示;关键信息是协议协商升到了 TLS 1.3、证书主体与有效期符合预期。把 -starttls xmpp 换成 -connect 直连 8080 可对 BOSH 端点做同类探测。
六、协议级排查:裸 XMPP 流 + stanza.log 双向核对
怀疑客户端行为不标准时,绕开客户端直接对服务器说话。最小探测脚本(python 标准库,只读流头):
python3 -c "
import socket
s = socket.create_connection(('127.0.0.1', 5222), 10)
s.sendall(b\"<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='vysper.org' version='1.0'>\")
print(s.recv(4096).decode()[:300])
s.close()"
实测输出:
<?xml version="1.0" encoding="UTF-8"?><stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" from="vysper.org" version="1.0" id="7f3ca97451c546a3a86ee8f7ba8a1ef7"><stream:features xmlns:stream="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required></required></starttls><register xmlns="http://jabber.org/features/iq-register"></register></stream:features>
这个回显信息量很大:from="vysper.org" 确认域名;<starttls><required/> 说明明文通道只允许升级;<register/> 说明 XEP-0077 带内注册已启用。同一时刻 tail stanza.log 应出现对应的流头记录,两侧对不上就查网络中间层。
💡 技术拓展:XMPP 流是双向 XML 流,服务器对不合法 XML 或未按协议走的连接会直接断开并可能回
<stream:error>;裸流探测时逐条等应答、按<required/>顺序推进(STARTTLS → 认证 → 绑定),比一次性灌入全部报文更接近真实客户端行为。
七、在线管理命令:XEP-0133 服务管理
发行包默认启用了 XEP-0133 Service Administration(admin@vysper.org 在 addAdmins 列表)。它跑在 XEP-0050 ad-hoc 命令框架上,节点 http://jabber.org/protocol/admin#add-user 用于加用户,流程三步:execute 拿表单 → submit → completed。
完整可用脚本(/root/xep0133.py,依赖 B1 的连接骨架):
#!/usr/bin/env python3
# XEP-0133 add-user:execute 取表单 -> submit 提交 -> completed -> 新账号登录验证
import re
from xmpp_client import C, DOMAIN # 复用 B1《安装指南》的 XMPP 客户端骨架
admin = C('admin', 'admin', 'q1w2e3r4')
admin.login('adminres')
# 1) execute:取表单
admin.send(f"<iq type='set' id='ex1' from='{admin.full_jid}' to='{DOMAIN}'>"
f"<command xmlns='http://jabber.org/protocol/commands' "
f"node='http://jabber.org/protocol/admin#add-user' action='execute'/></iq>")
r = admin.recv()
sid = re.search(r"sessionid='([^']+)'", r.replace('"', "'")).group(1)
print('form sessionid =', sid)
# 2) submit:字段名必须用 accountjid / password / password-verify
admin.send(f"<iq type='set' id='ex2' from='{admin.full_jid}' to='{DOMAIN}'>"
f"<command xmlns='http://jabber.org/protocol/commands' "
f"node='http://jabber.org/protocol/admin#add-user' sessionid='{sid}' action='complete'>"
f"<x xmlns='jabber:x:data' type='submit'>"
f"<field var='FORM_TYPE'><value>http://jabber.org/protocol/admin</value></field>"
f"<field var='accountjid'><value>user3@{DOMAIN}</value></field>"
f"<field var='password'><value>q1w2e3r4</value></field>"
f"<field var='password-verify'><value>q1w2e3r4</value></field>"
f"</x></command></iq>")
admin.recv()
# 3) 新账号登录验证
u3 = C('user3', 'user3', 'q1w2e3r4')
u3.login('u3res')
print('=== user3 LOGIN OK -> XEP-0133 add-user 生效')
执行 timeout 90 python3 xep0133.py,实测关键回显:
execute 应答的服务器表单(字段名就在里面,照抄即可):
<command ... status="executing"><x xmlns="jabber:x:data" type="form"><instructions>Fill out this form to add a user.</instructions><title>Adding a User</title>
<field var="FORM_TYPE" type="hidden"><value>http://jabber.org/protocol/admin</value></field>
<field var="accountjid" label="The Jabber ID for the account to be added" type="jid-single"/>
<field var="password" label="The password for this account" type="text-private"/>
<field var="password-verify" label="Retype password" type="text-private"/>
<field var="email" .../><field var="given_name" .../><field var="surname" .../></x></command>
submit 后的确认:
<iq ... type="result" id="ex2"><command ... sessionid="87581f1f7c8a46d6b29d5f90e9aae354" status="completed"></command></iq>
新账号立即登录:
=== [user3] login OK, full jid = user3@vysper.org/83072d57063443e28d013eb518471b98
=== user3 LOGIN OK -> XEP-0133 add-user 生效
两个实测注意点:① 字段名是 accountjid(单数、jid-single)——照抄较新 XEP-0133 修订的 accountjids 会得到错误应答;② 新账号落在当前存储注册器里,纯内存模式下重启即丢,持久化前提是先切 JCR 存储(《Apache Vysper 配置参数详解》2.1 节有跨重启存活的对照实测)。
八、用户自助注册:XEP-0077 带内注册
在 config/spring-config.xml 的 modules 列表加一行(详情见《Apache Vysper 配置参数详解》2.6 节):
<bean class="org.apache.vysper.xmpp.modules.extension.xep0077_inbandreg.InBandRegistrationModule"/>
重启后流特性出现 <register xmlns="http://jabber.org/features/iq-register"/>(第六节回显可见)。自助注册就是一条 iq:
timeout 90 python3 xep0077_final.py
实测关键回显:
>>> [reg] <iq type='set' id='r1' to='vysper.org'><query xmlns='jabber:iq:register'><username>user5</username><password>q1w2e3r4</password></query></iq>
<<< [reg] <iq xmlns="jabber:client" from="vysper.org" type="result" id="r1"></iq>
=== [user5] login OK
=== USER5 -> ADMIN MESSAGE OK (XEP-0077 on Spring runtime)
type='result' 即注册成功,新账号立刻能登录并投递消息(接收方必须在线——Vysper 0.7 没有离线消息存储,先发后上线的消息会被丢弃,这是实测确认过的行为差异,不是 bug)。
九、非 Spring 内存运行时:一行命令起一个 XMPP 服务器
发行包里还藏着一个不读 spring-config.xml 的启动类:org.apache.vysper.xmpp.server.ServerMain(注意与 run.sh 用的 org.apache.vysper.spring.ServerMain 区分)。它全内存运行、内置一组默认模块(含 XEP-0077 与 XEP-0133),两个系统属性控制行为:
| 系统属性 | 作用 |
|---|---|
vysper.admin.initial.password | 初始 admin@vysper.org 的密码(必须设置,否则口令随机生成) |
vysper.add.module | 额外加载的模块类名,逗号分隔多个 |
9.1 直接启动的失败路径(实测)
cd /opt/vysper/vysper-0.7
/opt/jdk/jdk8u504-b01/bin/java -Dvysper.admin.initial.password=q1w2e3r4 -cp "config:lib/*" org.apache.vysper.xmpp.server.ServerMain
实测输出:
Exception in thread "main" java.io.FileNotFoundException: src/main/config/bogus_mina_tls.cert (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at org.apache.vysper.xmpp.server.XMPPServer.setTLSCertificateInfo(XMPPServer.java:95)
at org.apache.vysper.xmpp.server.ServerMain.main(ServerMain.java:90)
这个类把证书路径硬编码为 src/main/config/bogus_mina_tls.cert——那是源码工程的目录布局,二进制发行包里没有。这也是该类更适合开发者而非运维的证据。workaround 很简单,按它要的布局补一个:
cd /opt/vysper/vysper-0.7
mkdir -p src/main/config && cp config/bogus_mina_tls.cert src/main/config/
9.2 启动与验证
nohup /opt/jdk/jdk8u504-b01/bin/java -Dvysper.admin.initial.password=q1w2e3r4 \
-cp "config:lib/*" org.apache.vysper.xmpp.server.ServerMain > /root/vysper-nonspring.log 2>&1 &
sleep 12
ss -tlnp | grep 5222
grep -m1 "adding module" /root/vysper-nonspring.log
实测输出:
LISTEN 0 50 *:5222 *:* users:(("java",pid=4836,fd=113))
07:15:21,140 | INFO | org.apache.vysper.xmpp.server.DefaultServerRuntimeContext | adding module... XEP-0133 Service Administration (1.1)
在此实例上执行第八节的 XEP-0077 注册脚本,实测成功(注册应答 type="result"、user5 登录 OK)。
-Dvysper.add.module 动态加载 XEP-0060 PubSub:
/opt/jdk/jdk8u504-b01/bin/java -Dvysper.add.module=org.apache.vysper.xmpp.modules.extension.xep0060_pubsub.PublishSubscribeModule \
-Dvysper.admin.initial.password=q1w2e3r4 \
-cp "config:lib/*" org.apache.vysper.xmpp.server.ServerMain
实测日志:
07:16:30,468 | INFO | org.apache.vysper.xmpp.server.DefaultServerRuntimeContext | adding module... XEP-0060 Publish-Subscribe (1.13rc3)
测试完 kill 掉并按第二节流程恢复 Spring 实例即可。这个运行时适合两个场景:不碰配置文件快速验证模块行为;本地开发时当一次性内存服务器。它同样监听 5222,与 Spring 实例不能并存。
十、演示程序实况:没有 demobot,有源码级 Swing 客户端
在 0.7 的二进制发行包与完整源码树里检索 demo/bot 关键字——如实给出阴性结论:发行包 bin/ 只有 run.sh/run.bat,lib/ 里没有任何 demo/bot jar;完整源码包(vysper-0.7-src.tar.gz)中与"演示"相关的只有两处:
tar tzf vysper-0.7-src.tar.gz | grep -E "vysper-0.7-src/(demo|examples)/" | cut -d/ -f2-3 | sort -u
实测输出:
demo/
demo/pubsub
examples/
examples/embedded-war
examples/pom.xml
| 位置 | 内容 | 实测状态 |
|---|---|---|
demo/pubsub/client | PubsubClientGUI——Swing 图形界面 XMPP 客户端,演示 XEP-0060 发布订阅 | 源码级,需 Maven 构建(pom 声明的是 Maven 2 时代插件,本机未构建实测) |
examples/embedded-war | 把 Vysper 内嵌进 Web 应用的 WAR 示例 | 同上 |
所以:网上流传的「Vysper 自带 demobot 机器人」并不存在于 0.7 发行包;想看协议行为,最直接的就是本文第四节的 stanza.log + 第七、八节的脚本实测。如果需要,把《Ubuntu 22.04 安装 Apache Vysper 指南》第七节的 xmpp_client.py 改成循环读 stdin 发消息,十行代码就是一个小 bot——但那是自己写的,不是 Vysper 自带的。
十一、常用操作速查表
| 目的 | 命令 |
|---|---|
| 启动(后台) | cd /opt/vysper/vysper-0.7 && nohup bin/run.sh > /root/vysper-opt.log 2>&1 & |
| 停止 | kill $(ps -ef | awk '/[S]erverMain/{print $2}') |
| 确认端口 | ss -tlnp | grep 5222 |
| 确认 JVM 参数 | jps -lv | grep ServerMain |
| 线程快照 | jstack $(pgrep -f ServerMain | head -1) |
| 实时报文 | tail -f log/stanza.log |
| 运行日志 | tail -f log/vysper_server.log |
| TLS 探测 | openssl s_client -starttls xmpp -connect 127.0.0.1:5222 |
| 流头探测 | python 裸流脚本(第六节) |
| 在线加用户 | XEP-0133 脚本(第七节) |
| 自助注册验证 | XEP-0077 脚本(第八节) |
| 内存一次性实例 | 第九节 java -D... org.apache.vysper.xmpp.server.ServerMain |
至此,Vysper 0.7 日常运维所需的命令与工具已全部过完。安装过程见《Ubuntu 22.04 安装 Apache Vysper 指南》,配置项逐条含义见《Apache Vysper 配置参数详解》,产品定位与选型背景见《Apache Vysper 介绍与选型指南》。