概述
在ShenYu v2.6.1, ShenYu注册中心只支持http类型,中间件注册类型已经被移除。 所以,请使用http注册类型来注册你的服务。不是微服务注册中心,它只是将元数据、选择器数据、规则数据注册到shenyu-admin,shenyu-admin将数据同步到shenyu-gateway。
插件
选择器和规则:一个插件有多个选择器,一个选择器对应多种规则。选择器相当于是对流量的一级筛选,规则就是最终的筛选。

包括:
- HTTP Process:
- ContextPath:上下文路径;
- ModifyResponse:响应修改;
- ParamMapping:
- Redirect:
- Request:
- Rewrite:
- Proxy:
- Divide:
- Dubbo:
- gRPC:
- Motan:
- Mqtt:
- Sofa:
- Spring Cloud:
- Tars:腾讯开源RPC框架;
- Tcp:
- WebSocket:
- Fault-Tolerance:容错插件
- Hystrix:
- RateLimiter:
- Resilience4j:
- Sentinel:
- Security:
- Casdoor:
- CryptorRequest:
- CryptorResponse:
- JWT:
- OAuth2:
- Sign:
- Waf:
- Observability:
- Aliyun SLS:
- Logging-ElasticSearch:
- Logging-Huawei LTS:
- Logging-Kafka:
- Logging:
- Logging-Pulsar:
- Logging-RabbitMQ:
- Logging-RocketMQ:
- Logging-Tencent-Cls:
- Metrics:
- Common:目前仅有一个General-Context:
- Cache:目前仅有一个Cache:
- Mock:目前仅有一个Mock:
- AI:
- AI Prompt:
- AI Proxy:
- AI TokenLimiter:
参考插件中心
选择器和规则
在PluginList->Proxy->Divide
页面,新增Selector时,可快速配置:
同样地,对于Rules,也可快速配置:
自动配置
在Nacos做如下配置后:
yaml
shenyu:
register:
registerType: http
serverLists: http://${GATEWAY_ADMIN_ADDR:88.100.29.241:9095}
props:
username: ${GATEWAY_ADMIN_USERNAME:admin}
password: ${GATEWAY_ADMIN_PASSWORD:123456}
client:
http:
props:
contextPath: ${SHENYU_CONTEXT_PATH:ems_admin_dev}
host: ${POD_IP:8.130.15.145}
discovery:
enable: true
protocol: http://
type: nacos
serverList: ${NACOS_ADDR:88.100.29.241:8848}
registerPath: ${SHENYU_REGISTER_PATH:ems_admin_dev}
props:
nacosNameSpace: gateway
groupName: DEFAULT_GROUP
username: ${NACOS_USERNAME:nacos}
password: ${NACOS_PASSWORD:nacos}
可自动创建Divide插件:
前文出现的,默认3次,默认3秒,估计在ShenYu源码里配置化的。
源码如下:
java
自动配置原理:有待进一步调研。
Sa-Token
ShenYu可集成Sa-Token。
点击右侧的Edit:
配置Sa-Token使用的Redis地址。
注册
有些服务使用IP注册。
无法自动注册的服务,如Python服务,使用应用名:
如何实现??
问题
错误码
404
请求服务A接口正常:
请求服务B报错404:
解决方法:重启服务B。
408
某个接口请求报错,信息如下:
json
{
"code": 408,
"message": "Request timeout, the maximum number of retry times has been exceeded"
}
排查此请求全链路涉及到的所有服务,检查retryCount
和timeout
配置
配置超时次数和时间:
记住上图的headerMaxSize和requestMaxSize,后面还会提到。
邮件发送4次
还是上面这个retryCount
配置导致的问题,不过报错码并不是408,也没有直接且明确地告诉你:Request timeout, the maximum number of retry times has been exceeded
。
因此排查起来略微花费一点时间。
背景:postman请求接口,模拟定时任务执行,定时任务是判断收件人,抄送人,开启状态,查询MySQL数据库,获取Groovy脚本,解析Groovy脚本并执行,然后获取结果。脚本里写MySQL查询语句,获取查询结果后,作为附件发送出去。理论上只应该收到一封邮件,结果却几乎同一时间收到4次一模一样的邮件。
经过排查后,定位到ShenYu配置的超时次数是3次,超时时间为3秒;超时3次后,不再继续重试,即前前后后发起4次请求。
附录:
groovy
package com.tesla.admin.service
import cn.hutool.core.date.DateUtil
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.jdbc.core.JdbcTemplate
class SendMail {
@Autowired
JdbcTemplate jdbcTemplate
// {
// mainTitle: \'\', //主标题
// mainContent: \'\', //主内容
// subTitle: \'\', //副标题
// listing: { //如果邮件是个列表}
// table: { //如果邮件是个表格
// name: \'\',
// columns: [
// {
// title: \'\', //标题
// width: \'\', //宽度
// field: \'id\', //数据字段
// }
// ],
// data: [
// {
// id: \'1\'
// }
// ]
// }
// detail: {
// header: \'\',
// body: \'\',
// footer: \'\'
// }
// }
def run() {
DynamicDataSourceContextHolder.push("mysql1")
try {
def results = jdbcTemplate.queryForList("""
SELECT device_position
FROM ems.energy_consumption_analysis
WHERE acquisition_month = month(now()) - 1
GROUP BY device_position
ORDER BY abs(mom_rate) DESC;
""")
def tableDef = [
name : \'异常详情\',
columns: [
[title: \'设备位置\', width: \'250\', field: \'device_position\']
],
data : results
]
return [
mainTitle : \'尊敬的用户,您好!\',
mainContent : "附件是上月(${DateUtil.month(new Date())}月份)内所有用能异常情况汇总,请您下载查阅。",
table : tableDef, // 附件使用
hideTableInBody : true, // 模板用以跳过渲染
detail : [
footer: \'系统自动发送,请勿回复。\'
],
]
} catch (Exception e) {
log.error("groovy run error: ${e.message}")
} finally {
DynamicDataSourceContextHolder.poll()
}
}
}
413
报错信息:Request entity too large 请求实体太大
。
出现此报错原因在于,ShenYu里配置过headerMaxSize和requestMaxSize,且该值过小。一般情况下,这两个值都是0,即没有限制。
解决方法:设置为0,或放大配置值。
-106
-107
通过网关请求某个服务时报错:
json
{
"code": -107,
"message": "divide:Can not find selector, please check your configuration!"
}
可能的原因:
- 该环境(dev、test或prod)没有发布过这个服务;
- 写错服务名字:
-119
请确认接口经过网关,且satoken插件配置正常

解决方法:
无法修改注册IP
在修改注册IP时遇到告警,无法修改:
解决方法:删除整个服务的配置信息,然后重新添加配置+(自动或手动)注册IP。
无法删除注册IP
正常情况下的服务注册
遇到的问题如下,找不到删除按钮:
Pod异常,ShenYu没有自动剔除该异常Pod的注册信息;因此,页面上看到的IP肯定有问题;流量请求到不存在的IP。但是无法删除。
解决方法:只能手动删除整个配置,然后重新配置。
至于为什么ShenYu没有自动剔除异常Pod注册的IP,这才是根本问题。
OOM
几乎(所有需要经过ShenYu网关)全部接口超时异常:
如上图所示,一般是20秒左右定义为【超时】。
排除掉阿里云ALB、网络、k8s集群等可能原因之后,将问题定位在ShenYu网关上。
生产环境,gateway pod设置为3副本:
逐个查看pod日志,发现其中只有一个pod有异常,且时间停留在17点01分:
具体的报错日志:
2025-07-02 10:08:13 [shenyu-netty-epoll-5] [traceId= spanId= sampled=] INFO com.tesla.gateway.plugin.SatokenPlugin - CheckAndRemoveKeySet: conversation_id:44b81c59-3a26-480c-bb66-ba44a6ee2692, step: false
Exception in thread "AsyncAppender-Worker-ASYNC_FILE" Exception in thread "AsyncAppender-Worker-ASYNC_STDOUT" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3745)
at java.base/java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:172)
at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:538)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:178)
at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:39)
at ch.qos.logback.core.pattern.CompositeConverter.convert(CompositeConverter.java:24)
at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:36)
at ch.qos.logback.core.pattern.PatternLayoutBase.writeLoopOnConverters(PatternLayoutBase.java:115)
at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:165)
at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:39)
at ch.qos.logback.core.encoder.LayoutWrappingEncoder.encode(LayoutWrappingEncoder.java:116)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:230)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:290)
java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3745)
at java.base/java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:172)
at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:538)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:178)
at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:39)
at ch.qos.logback.core.pattern.CompositeConverter.convert(CompositeConverter.java:24)
at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:36)
at ch.qos.logback.core.pattern.PatternLayoutBase.writeLoopOnConverters(PatternLayoutBase.java:115)
at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:165)
at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:39)
at ch.qos.logback.core.encoder.LayoutWrappingEncoder.encode(LayoutWrappingEncoder.java:116)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:230)
at ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:235)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.core.AsyncAppenderBase$Worker.run(AsyncAppenderBase.java:290)
出问题的pod只有一个,但现象是gateway作为一个服务,可以接收新的请求,但是全部接口都超时。
观察Grafana面板,10点多有一个内存使用率的【非常小】的跃升,哪怕是跃升之后,内存使用也不过900多MiB:
k8s yaml文件定义如下:
限额是3G,远远没有达到k8s内存异常触发OOM自动重启的条件。
重启有问题的一个pod,接口请求报错:
{"code":-106,"message":"Can not find url, please check your configuration!"}
意思是gateway pod状态虽然是Running,但是得等pod加载配置成功。
出现-106,无需在页面(对应于gateway-admin服务)上做任何配置化操作。。。

groovy
bootRun {
ignoreExitValue true
jvmArgs('-Dspring.output.ansi.enabled=always',
'-noverify',
'-XX:TieredStopAtLevel=1',
'-Xmx1024m')
sourceResources sourceSets.main
}
yaml
logging:
level:
root: info
org.apache.shenyu.bonuspoint: info
org.apache.shenyu.lottery: info
org.apache.shenyu: debug
org.apache.shenyu.plugin.sync.data.websocket.client.ShenyuWebsocketClient: INFO
org.apache.shenyu.plugin.base.AbstractShenyuPlugin: WARN
org.apache.shenyu.plugin.api.ShenyuPlugin: debug
yaml
org.apache.shenyu.plugin.sync.data.websocket.client.ShenyuWebsocketClient: INFO
org.apache.shenyu.plugin.base.AbstractShenyuPlugin: WARN


- 可考虑将logback切换到性能更强的log4j2日志框架:
https://logging.apache.org/log4j/2.12.x/performance.html