Apache ShenYu 常用 CLI 命令与工具详解
汇总 Apache ShenYu 2.7.1 日常运维最常用的命令与工具,含 start.sh 启停、ss 与 jps 进程端口校验、curl 登录管理端获取 token、REST 注册 divide 选择器规则上游、actuator 健康检查与 systemd 托管命令,全部输出均来自实测环境
Apache ShenYu 常用 CLI 命令与工具详解
目标:汇总 Apache ShenYu 2.7.1 日常运维最常用的命令与工具,含 start.sh 启停、ss 与 jps 进程端口校验、curl 登录管理端获取 token、REST 注册 divide 选择器规则上游、actuator 健康检查与 systemd 托管命令,全部输出均来自实测环境。
一、环境信息
| 项目 | 说明 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| ShenYu 版本 | 2.7.1(二进制部署,/opt/apache-shenyu-2.7.1-admin-bin、/opt/apache-shenyu-2.7.1-bootstrap-bin) |
| admin | 9095 端口,bin/start.sh、bin/stop.sh |
| bootstrap | 9195 端口,bin/start.sh、bin/stop.sh |
| 命令行工具 | curl、ss(iproute2)、jps、jcmd(JDK 17 自带)、python3(JSON 解析) |
| 示例账号 | admin / q1w2e3r4 |
二、工具概览
ShenYu 没有单独的运维 CLI,日常操作由四类命令组成:
| 类别 | 工具 | 用途 |
|---|---|---|
| 进程管理 | bin/start.sh、bin/stop.sh、systemctl | 双进程启停与开机自启 |
| 状态校验 | ss、jps、ps、curl /actuator/health | 端口、进程、堆参数、健康状态 |
| 配置管理 | curl(管理端 REST API) | 登录、选择器、规则、上游、插件查询 |
| 排障 | tail、grep 日志文件 | 启动异常、同步链路、代理命中记录 |
三、前置条件
- 双进程已按《Apache ShenYu 安装指南》部署并可正常启动。
- 已安装 curl 与 iproute2(ss 命令):
sudo apt-get install -y curl iproute2。 - 演示后端已就绪(python3 -m http.server 8500)。
- 管理端登录 token 有效期 24 小时,过期需重新登录。
四、工具详解
4.1 服务管理命令(start.sh 与 stop.sh)
启动 admin(ADMIN_JVM 注入堆参数):
$ export ADMIN_JVM='-server -Xms256m -Xmx256m -Xmn128m'
$ cd /opt/apache-shenyu-2.7.1-admin-bin/bin && ./start.sh
Start with the environment variable JAVA_OPTS set: -server -Xms256m -Xmx256m -Xmn128m
Starting the ShenYu-Admin ...
Please check the log files: /opt/apache-shenyu-2.7.1-admin-bin/logs/shenyu-admin.log
启动 bootstrap(BOOT_JVM 注入堆参数):
$ export BOOT_JVM='-server -Xms256m -Xmx256m -Xmn128m'
$ cd /opt/apache-shenyu-2.7.1-bootstrap-bin/bin && ./start.sh
Start with the environment variable JAVA_OPTS set: -server -Xms256m -Xmx256m -Xmn128m
Starting the ShenYu-Bootstrap ...
Please check the log files: /opt/apache-shenyu-2.7.1-bootstrap-bin/logs/shenyu-bootstrap.log
停止进程:
$ /opt/apache-shenyu-2.7.1-admin-bin/bin/stop.sh
$ /opt/apache-shenyu-2.7.1-bootstrap-bin/bin/stop.sh
$ ps -ef | grep [j]ava | wc -l
0
注意:start.sh 把 java 放入后台后脚本本身退出,适合交互运维;systemd 托管时不要用 Type=simple 直接跑 start.sh(实测会因脚本退出被反复重启),应直接托管 java 主进程(见 4.4)。
4.2 端口与 JVM 校验工具
ss 确认监听:
$ ss -tlnp | grep -E '9095|9195'
LISTEN 0 100 *:9095 *:* users:(("java",pid=5996,fd=333))
LISTEN 0 128 *:9195 *:* users:(("java",pid=6108,fd=574))
jps 确认主类:
$ jps -l
8439 org.apache.shenyu.admin.ShenyuAdminBootstrap
8533 org.apache.shenyu.bootstrap.ShenyuBootstrapApplication
jps -v 确认堆参数生效:
$ jps -v | grep ShenyuAdmin | tr ' ' '\n' | grep -E 'Xms|Xmx'
-Xms256m
-Xmx256m
ps 确认双进程参数一致:
$ ps -ef | grep [j]ava | grep -oE 'Xms256m -Xmx256m' | sort | uniq -c
2 Xms256m -Xmx256m
actuator 健康检查:
$ curl -s http://localhost:9095/actuator/health
{"status":"UP"}
$ curl -s http://localhost:9195/actuator/health
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":843834499072,"free":330458386432,"threshold":10485760,"path":"/opt/apache-shenyu-2.7.1-bootstrap-bin/.","exists":true}},"ping":{"status":"UP"},"refreshScope":{"status":"UP"}}}
4.3 管理端登录与 REST API(curl)
登录并提取 token(2.7.1 登录接口为 GET,参数名 userName):
$ curl -s 'http://localhost:9095/platform/login?userName=admin&password=q1w2e3r4'
{"code":200,"message":"login dashboard user success","data":{"id":"1","userName":"admin","role":1,"enabled":true,"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwiZXhwIjoxNzkxODU5MTU2fQ.DCHfswN-SAqZW2NVoDnmL4i7hq6tarlciceYGKC4rr8","expiredTime":86400000}}
脚本化提取(用 python3 解析,环境未装 jq):
$ TOKEN=$(curl -s 'http://localhost:9095/platform/login?userName=admin&password=q1w2e3r4' | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['token'])")
查询插件清单,确认 divide 插件编号(请求头 X-Access-Token 携带 token):
$ curl -s 'http://localhost:9095/namespace-plugin/listByNamespace?namespace=649330b6-c2d7-4edc-be8e-8a54df9eb385' -H "X-Access-Token: $TOKEN" | python3 -c "
import json,sys
d=json.load(sys.stdin)
for p in d['data']:
if p.get('name')=='divide': print(p['id'], p['enabled'])
"
5 True
创建 divide 选择器(注意 matchRestful 必填):
$ SELID=$(curl -s -X POST http://localhost:9095/selector -H "X-Access-Token: $TOKEN" -H "Content-Type: application/json" -d '{
"pluginId": "5", "name": "http-backend", "matchMode": 0, "type": 0, "sort": 1,
"enabled": true, "loged": true, "continued": true, "matchRestful": false,
"handle": "[]", "selectorConditions": [],
"namespaceId": "649330b6-c2d7-4edc-be8e-8a54df9eb385" }' | python3 -c "import json,sys; print(json.load(sys.stdin)['data'])")
$ echo $SELID
2109479217540501504
创建规则(URI 精确匹配 /index.html):
$ curl -s -X POST http://localhost:9095/rule -H "X-Access-Token: $TOKEN" -H "Content-Type: application/json" -d '{
"selectorId": "2109479217540501504", "name": "index-html", "matchMode": 0, "sort": 1,
"enabled": true, "loged": true, "matchRestful": false,
"handle": "{\"loadBalance\":\"random\",\"retry\":0,\"timeout\":3000}",
"ruleConditions": [{"paramType":"uri","operator":"=","paramName":"/","paramValue":"/index.html"}],
"namespaceId": "649330b6-c2d7-4edc-be8e-8a54df9eb385" }'
{"code":200,"message":"create success","data":1}
绑定本地服务发现上游(dashboard 前端同款接口,正确路径是 binding 而非 addProxySelector):
$ curl -s -X POST http://localhost:9095/proxy-selector/binding -H "X-Access-Token: $TOKEN" -H "Content-Type: application/json" -d '{
"selectorId": "2109479217540501504", "name": "http-backend", "pluginName": "divide",
"type": "local", "forwardPort": 8500, "listenerNode": "", "handler": "{}", "props": "{}",
"discovery": {"discoveryType": "local", "serverList": "", "props": "{}", "name": "http-backend"},
"discoveryUpstreams": [{"protocol": "http://", "url": "localhost:8500", "status": 1, "weight": 50, "props": "{}"}],
"namespaceId": "649330b6-c2d7-4edc-be8e-8a54df9eb385" }'
{"code":200,"message":"create success","data":null}
经网关验证代理:
$ curl -s http://localhost:9195/index.html
<h1>Hello from backend on port 8500</h1>
4.4 系统托管与日志命令
systemd 服务单元与管理命令(单元文件全文见《Apache ShenYu 安装指南》第六章):
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now shenyu-admin
$ sudo systemctl enable --now shenyu-gateway
$ systemctl is-active shenyu-admin
active
$ systemctl is-enabled shenyu-gateway
enabled
日志排障常用组合:
$ tail -f /opt/apache-shenyu-2.7.1-admin-bin/logs/shenyu-admin.log # 管理端实时日志
$ tail -f /opt/apache-shenyu-2.7.1-bootstrap-bin/logs/shenyu-bootstrap.log # 网关实时日志
$ grep 'handleResult' /opt/apache-shenyu-2.7.1-bootstrap-bin/logs/shenyu-bootstrap.log | tail -3 # 配置同步事件
$ grep -E 'divide (selector|rule) success' /opt/apache-shenyu-2.7.1-bootstrap-bin/logs/shenyu-bootstrap.log # 代理命中记录
网关日志典型输出(代理命中时):
divide selector success match , selector name :http-backend
divide rule success match , rule name :index-html
五、注意事项
- token 获取后存入变量复用,不要在每条命令里重复登录;token 过期返回 401 或要求重新登录。
- POST /selector 缺少 matchRestful 字段会报
invalid argument [matchRestful: must not be null]。 - 上游绑定接口二选一时用 /proxy-selector/binding;/proxy-selector/addProxySelector 面向 tcp 代理选择器(内部固定 pluginName tcp),用于 divide 不生效,实测误用后应 DELETE /proxy-selector/batch 清理。
- bootstrap 的 shenyu.upstreamCheck.enabled 需为 true,否则新上游永远不进健康列表,代理报 -119。
- H2 内存库下 admin 重启即清空配置,批量注册命令建议存成脚本,重启后重放。
- 命名空间 ID 全部接口保持一致(649330b6-c2d7-4edc-be8e-8a54df9eb385),不一致则配置不同步到网关。
六、常见问题
6.1 curl 登录返回 405 或 POST method is not supported
2.7.1 的登录接口只接受 GET:curl -s 'http://localhost:9095/platform/login?userName=admin&password=q1w2e3r4'。参数名是 userName 而非 username,写错会返回 username or password error。
6.2 接口全部返回 401 或提示认证失败
业务接口需请求头 X-Access-Token,检查三件事:token 是否过期(24 小时有效期);请求头名是否精确为 X-Access-Token;admin 是否重启过(重启后旧 token 全部失效,需重新登录)。
6.3 网关代理返回 -119 或 -107
-107 Can not find selector:选择器数据未同步或 admin 重启后 H2 清空,重新注册即可。 -119 Can not find healthy upstream url:上游健康检查未开启,将 bootstrap 的 shenyu.upstreamCheck.enabled 改为 true 并重启 bootstrap。
6.4 stop.sh 之后进程仍在
确认 grep 的对象:stop.sh 按启动脚本自身记录处理,若进程曾由其他方式拉起可能漏杀。统一用主类名兜底清理:
$ ps ax | grep ShenyuAdminBootstrap | grep -v grep | awk '{print $1}' | xargs -r kill
七、参考链接
- ShenYu 管理端 REST 接口文档:https://shenyu.apache.org/docs/index/
- swagger 根路径(admin 运行时):http://localhost:9095/v3/api-docs
- 源码仓库:https://github.com/apache/shenyu