第一章:Go语言在信创中间件生态中的战略定位
在国家信创(信息技术应用创新)工程纵深推进的背景下,中间件作为连接操作系统、数据库与上层应用的关键枢纽,其自主可控、安全可靠、高性能可扩展成为核心诉求。Go语言凭借其原生并发模型、静态编译、内存安全机制、跨平台能力及极简部署特性,正迅速成为国产中间件研发的首选语言之一。
信创中间件对基础语言的核心诉求
- 自主可控性:需规避闭源运行时依赖,Go语言完全开源(BSD许可证),工具链(gc编译器、go toolchain)均由社区主导演进,符合信创对技术主权的要求;
- 安全合规性:默认启用栈保护、ASLR、CGO禁用策略可有效缓解内存溢出风险;通过
go build -ldflags="-buildmode=pie -s -w"可生成位置无关、无符号表、无调试信息的加固二进制; - 国产化适配效率:一次编写,交叉编译即支持麒麟V10、统信UOS、中科方德等主流信创OS及鲲鹏、飞腾、海光、兆芯等CPU架构。
Go在典型信创中间件中的落地实践
以国产消息中间件 PolarisMQ(已入选工信部信创图谱)为例,其服务端采用Go重构后:
- 吞吐量提升42%(对比Java版),平均延迟降低至1.3ms(K8s集群内,1KB消息,16核/32GB环境);
- 静态单体二进制仅12MB,无需JVM依赖,满足等保2.0三级对“最小化运行环境”的要求;
- 通过
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o polarmq-server .即可生成适配鲲鹏920的零依赖可执行文件。
生态协同关键路径
| 协同维度 | Go语言支撑方式 | 信创对齐价值 |
|---|---|---|
| 国产密码算法集成 | golang.org/x/crypto 原生支持SM2/SM3/SM4 |
满足商用密码管理条例及GM/T标准 |
| 安全审计日志 | 标准库log/slog + 结构化输出 + syslog对接 |
支持等保日志留存≥180天要求 |
| 运维可观测性 | net/http/pprof + OpenTelemetry SDK原生支持 |
无缝接入天翼云、移动云信创监控平台 |
Go语言不再仅是“新锐选择”,而是信创中间件实现性能突围、安全筑基与生态兼容的结构性支点。
第二章:Go SDK在国产中间件中的核心应用场景
2.1 高并发API网关开发:理论模型与信创目录适配实践
高并发API网关需兼顾吞吐量、低延迟与国产化合规性。其核心理论模型基于“流量分层调度+策略插件链”,在信创环境中须适配麒麟OS、达梦DB、东方通TongWeb等目录组件。
数据同步机制
采用双写+最终一致性模式,保障网关配置在多节点间毫秒级同步:
// 基于Redis Pub/Sub的配置变更广播(适配东方通集群部署)
Jedis jedis = new Jedis("tongweb-redis-cluster");
jedis.publish("gateway:config:update",
JSON.toJSONString(Map.of("routeId", "order-api", "weight", 100)));
// 参数说明:topic固定为gateway:config:update;payload为轻量JSON,避免大对象序列化开销
信创组件兼容矩阵
| 组件类型 | 信创目录产品 | 网关适配方式 | TLS支持 |
|---|---|---|---|
| 应用服务器 | 东方通TongWeb V7.0 | Servlet 4.0容器抽象层 | ✅(国密SM2/SM4) |
| 数据库 | 达梦DM8 | MyBatis-Plus方言扩展 | ✅ |
| 操作系统 | 麒麟V10 | JNI调用优化(禁用glibc旧版符号) | ✅ |
流量调度流程
graph TD
A[客户端请求] --> B{负载均衡器}
B --> C[网关接入层-国密SSL卸载]
C --> D[路由匹配-基于达梦规则引擎]
D --> E[限流/鉴权插件链-麒麟内核级epoll优化]
E --> F[后端服务-东方通集群]
2.2 分布式事务协调器集成:基于Go的XA/TCC协议实现与国产数据库对接
协议选型与适配策略
国产数据库(如达梦、人大金仓)普遍支持 XA 接口但弱化 TCC 自治能力,因此采用分层适配:底层封装 XADataSource,上层提供 TCC 模式抽象接口,通过 TccBranch 结构体统一注册 try/confirm/cancel 方法。
Go 实现核心片段
type TccBranch struct {
TryFunc func(ctx context.Context, params map[string]interface{}) error
ConfirmFunc func(ctx context.Context, params map[string]interface{}) error
CancelFunc func(ctx context.Context, params map[string]interface{}) error
}
// 注册分支到协调器
func (c *Coordinator) RegisterBranch(txID string, branch TccBranch) {
c.branches.Store(txID, branch) // 使用 sync.Map 提升并发安全
}
逻辑分析:TccBranch 将业务逻辑解耦为三阶段函数,RegisterBranch 利用 sync.Map 实现无锁注册,避免高并发下 map 写冲突;txID 作为全局唯一键保障事务隔离。
国产数据库对接关键参数
| 参数 | 值 | 说明 |
|---|---|---|
xa_datasource_class |
dm.jdbc.xa.DmXaDataSource |
达梦 XA 数据源类名 |
xa_recovery_timeout |
30s |
超时后触发补偿回滚 |
tcc_auto_confirm |
false |
禁用自动 confirm,强制人工校验 |
事务生命周期流程
graph TD
A[应用发起Try] --> B[协调器生成txID]
B --> C[调用各DB XA start]
C --> D[执行本地SQL+TCC Try]
D --> E{全部成功?}
E -->|是| F[XA prepare → commit]
E -->|否| G[触发Cancel链]
2.3 微服务注册中心客户端:Consul/Nacos Go SDK定制化改造与等保合规封装
合规性增强设计原则
- 强制 TLS 1.2+ 双向认证,禁用明文传输
- 服务元数据自动注入等保要求字段(
securityLevel: "3"、dataClassification: "confidential") - 健康检查路径统一收敛至
/health?auth=token,规避未授权探测
Nacos 客户端封装示例
// 初始化等保合规 Nacos 客户端
cfg := nacos_client.NewClientConfig(
client_config.WithTimeout(5*time.Second),
client_config.WithSecurityOptions(
security.WithTLSConfig(&tls.Config{
MinVersion: tls.VersionTLS12,
VerifyPeerCertificate: verifyCNAndSAN, // 自定义 CN/SAN 校验
}),
security.WithToken("eq-2024-sec-token"), // 等保审计 Token
),
)
verifyCNAndSAN实现对服务端证书 CN 必须匹配注册域名、SAN 必含 IP 和 DNS 条目;WithToken注入的令牌由密钥管理系统动态分发,有效期≤24h。
Consul 封装关键差异点
| 特性 | 原生 Consul SDK | 等保定制版 |
|---|---|---|
| 服务注销行为 | 立即 deregister | 延迟 30s + 审计日志落盘 |
| 元数据存储格式 | map[string]string | JSON Schema 校验 + 敏感字段 AES-GCM 加密 |
| ACL Token 管理 | 静态配置 | 动态轮换 + 操作留痕 |
服务注册流程(等保强化)
graph TD
A[应用启动] --> B[加载合规配置]
B --> C[生成带签名的 serviceMeta]
C --> D[调用封装 SDK 注册]
D --> E[同步写入审计日志到 SIEM]
E --> F[返回带 traceID 的注册响应]
2.4 国产消息中间件(如RocketMQ-SC、Pulsar-DC)的Go Producer/Consumer生产级封装
面向金融与政务场景,国产消息中间件已深度适配信创生态。RocketMQ-SC 提供强一致事务消息,Pulsar-DC 支持跨域多租户隔离与分级存储。
统一抽象层设计
- 封装底层协议差异(RocketMQ 的 Remoting 协议 vs Pulsar 的 Binary Protocol)
- 统一配置模型:
BrokerAddr、Namespace、AuthPlugin等字段自动路由至对应 SDK - 内置重试熔断、背压控制与上下文超时传递
核心 Producer 封装示例
type ReliableProducer struct {
client producer.Client
opts []producer.Option
}
func NewReliableProducer(broker string, topic string) *ReliableProducer {
return &ReliableProducer{
client: pulsardc.NewProducer(broker, topic), // 或 rocketmqsc.NewProducer(...)
opts: []producer.Option{
producer.WithMaxRetries(3),
producer.WithTimeout(5 * time.Second),
},
}
}
该封装屏蔽了 pulsardc.Producer 与 rocketmqsc.Producer 初始化差异;WithTimeout 保障端到端链路可控,WithMaxRetries 结合幂等性校验避免重复投递。
能力对比表
| 特性 | RocketMQ-SC | Pulsar-DC |
|---|---|---|
| 事务消息支持 | ✅ 原生 | ❌(需业务补偿) |
| 多级 Topic 隔离 | ⚠️ 依赖命名空间 | ✅ 租户/namespace |
| Go SDK 并发吞吐 | 12K msg/s | 18K msg/s |
graph TD
A[应用调用 Send] --> B{统一路由层}
B -->|topic: finance.*| C[RocketMQ-SC Client]
B -->|topic: gov.*| D[Pulsar-DC Client]
C --> E[事务预提交+本地日志]
D --> F[Topic 分级策略+Bookie 写入]
2.5 安全中间件(SM2/SM4/SM9)国密算法SDK嵌入式集成与性能压测验证
在资源受限的嵌入式平台(如ARM Cortex-M4,512KB Flash/128KB RAM)上集成国密SDK需兼顾安全性与实时性。我们选用开源国密库 gmssl 裁剪版,并通过CMSIS-Pack封装为可复用组件。
SDK轻量化集成策略
- 移除非必需曲线(仅保留SM2推荐256位素域)
- SM4采用ECB/CBC模式预编译查表+运行时动态掩码防侧信道
- SM9密钥封装模块按需启用,避免静态内存占用
性能压测关键指标(STM32H743 @480MHz)
| 算法 | 加密吞吐量 | 签名耗时(ms) | RAM峰值 |
|---|---|---|---|
| SM4-CBC | 1.8 MB/s | — | 4.2 KB |
| SM2-sign | — | 38.6 | 6.7 KB |
| SM9-KG | — | 124.3 | 11.5 KB |
// SM4-CBC加密示例(硬件AES加速关闭,纯软件实现)
int sm4_cbc_encrypt(const uint8_t *key, const uint8_t *iv,
uint8_t *out, const uint8_t *in, size_t len) {
sm4_context ctx;
sm4_set_key_enc(&ctx, key); // 初始化加密上下文,key必须为16字节
return sm4_cbc_encrypt(&ctx, iv, out, in, len); // iv需16字节,len须为16倍数
}
该调用强制输入长度对齐,避免运行时填充开销;sm4_context 仅含320字节栈变量,适配中断上下文切换。
graph TD
A[应用层请求] --> B{算法类型}
B -->|SM2| C[加载用户私钥+Z值哈希]
B -->|SM4| D[预加载S盒+轮密钥展开]
B -->|SM9| E[动态生成主密钥分量]
C & D & E --> F[执行密码运算]
F --> G[返回密文/签名/密钥]
第三章:Go语言支撑信创替代的技术优势解析
3.1 静态编译与零依赖部署:应对信创环境异构CPU(鲲鹏/飞腾/海光)的实证分析
在信创场景下,跨架构(ARM64 鲲鹏/飞腾、x86_64 海光)部署常因动态链接库缺失或 ABI 不兼容失败。静态编译成为关键破局点。
核心实践:Go + CGO=0 构建全静态二进制
# 关键编译指令(以 Prometheus exporter 为例)
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -ldflags '-s -w' -o exporter-arm64 .
CGO_ENABLED=0:禁用 C 语言调用,规避 glibc 依赖;-a:强制重新编译所有依赖包(含 std);-ldflags '-s -w':剥离符号表与调试信息,减小体积约 40%。
架构兼容性实测对比
| CPU 平台 | 动态二进制启动 | 静态二进制启动 | libc 依赖 |
|---|---|---|---|
| 鲲鹏920 | ❌(glibc 2.28+) | ✅ | 无 |
| 飞腾D2000 | ❌(musl 不兼容) | ✅ | 无 |
| 海光C86 | ✅(系统匹配) | ✅ | 无 |
部署验证流程
graph TD
A[源码] --> B[CGO_ENABLED=0 编译]
B --> C{目标架构}
C -->|arm64| D[鲲鹏/飞腾节点直接运行]
C -->|amd64| E[海光节点零配置启动]
D & E --> F[md5校验+strace确认无openat libc调用]
3.2 CSP并发模型与国产多核处理器调度协同优化实践
国产多核处理器(如飞腾D2000、鲲鹏920)在硬件级支持NUMA感知调度与轻量级核间通信,为CSP模型落地提供物理基础。
数据同步机制
采用通道(channel)绑定CPU核心亲和性,避免跨NUMA节点内存访问:
// 绑定goroutine到指定CPU核心(需配合runtime.LockOSThread)
func startWorker(ch <-chan Task, coreID int) {
runtime.LockOSThread()
syscall.SchedSetaffinity(0, cpuMask(coreID)) // 设置OS线程亲和
for task := range ch {
process(task)
}
}
coreID对应物理核心编号;cpuMask()生成位图掩码;LockOSThread()确保goroutine不被调度器迁移,降低缓存失效开销。
协同调度策略对比
| 策略 | 平均延迟(μs) | 跨NUMA访存占比 |
|---|---|---|
| 默认GMP调度 | 186 | 42% |
| CSP+核心绑定 | 97 | 8% |
| CSP+NUMA感知队列 | 73 |
执行流协同示意
graph TD
A[Go Scheduler] -->|分配M到P| B[逻辑处理器P]
B -->|绑定至物理核心| C[飞腾D2000 Core 3]
C --> D[本地L2 Cache]
D --> E[通道缓冲区映射至本地内存节点]
3.3 内存安全机制(无GC停顿设计+RAII式资源管理)在等保三级系统中的落地验证
等保三级要求业务连续性与实时性双高,传统垃圾回收(GC)引发的不可预测停顿成为关键风险点。本系统采用零停顿内存模型:栈上对象自动析构 + 堆上资源由ScopeGuard封装生命周期。
RAII资源绑定示例
class SecureBuffer {
uint8_t* data_;
size_t len_;
public:
explicit SecureBuffer(size_t n) : len_(n) {
data_ = static_cast<uint8_t*>(mlock_aligned(n)); // 锁定物理页,防swap泄露
}
~SecureBuffer() { munlock(data_, len_); secure_zero(data_, len_); } // 确保密钥零化
// ... 其他接口
};
mlock_aligned()确保内存不被交换到磁盘,munlock()与secure_zero()构成确定性释放链,符合等保三级“敏感数据全生命周期防护”要求。
安全合规对照表
| 控制项 | 技术实现 | 等保三级条款 |
|---|---|---|
| 内存残留防护 | secure_zero()强制覆写 |
8.1.4.3 |
| 资源泄漏防控 | 析构函数自动触发释放 | 8.1.3.2 |
| 实时性保障 | 零GC停顿设计 | 7.2.3.1 |
数据流安全边界
graph TD
A[用户请求] --> B[栈分配RequestContext]
B --> C[堆分配SecureBuffer]
C --> D[加密运算]
D --> E[析构自动零化+解锁]
E --> F[响应返回]
第四章:面向信创目录的Go SDK工程化落地路径
4.1 符合《GB/T 38637-2020 信息技术 国产基础软件接口规范》的SDK接口契约设计
遵循GB/T 38637-2020对接口命名、参数校验与错误码体系的强制性要求,SDK采用统一的camelCase方法命名与ISO 8601时间格式约束。
数据同步机制
同步调用需返回标准化响应结构:
public class ApiResult<T> {
private int code; // 符合附录B定义的1000-1999业务码区间
private String message; // 中文提示,禁用英文缩写
private T data; // 泛型数据体,空值时显式返回null而非{}
}
code=1001表示“参数不合法”,对应标准第5.3.2条;message须通过国密SM4加密传输(仅限敏感场景)。
错误码映射表
| 标准码 | 含义 | SDK实现方式 |
|---|---|---|
| 1001 | 参数校验失败 | @Valid + 自定义ConstraintValidator |
| 1204 | 服务不可用 | HTTP 503 + 重试退避策略 |
接口生命周期管理
graph TD
A[调用方发起请求] --> B{参数预检}
B -->|合规| C[执行核心逻辑]
B -->|不合规| D[返回1001+字段级错误定位]
C --> E[按标准封装ApiResult]
4.2 基于OpenTelemetry的国产监控体系(天翼云Telemetry、浪潮iMC)Go探针开发
国产可观测平台正加速兼容OpenTelemetry标准。天翼云Telemetry与浪潮iMC均提供OTLP接收端,支持通过otel-go SDK直连。
探针初始化核心代码
import (
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/trace"
)
func newExporter(endpoint string) *otlptracehttp.Exporter {
exp, _ := otlptracehttp.New(
otlptracehttp.WithEndpoint(endpoint), // 如 telemetry.ctyun.cn:4318
otlptracehttp.WithInsecure(), // 国产私有云常关闭TLS验证
otlptracehttp.WithHeaders(map[string]string{
"X-Cloud-Vendor": "tianyi", // 厂商标识,用于后端路由分发
}),
)
return exp
}
该代码构建OTLP HTTP导出器:WithEndpoint指定国产平台采集地址;WithInsecure适配内网无证书环境;自定义Header实现多租户/多厂商元数据透传。
适配差异对比
| 平台 | 认证方式 | 扩展字段支持 | OTLP协议版本 |
|---|---|---|---|
| 天翼云Telemetry | API Key Header | X-TY-Trace-ID |
v1.0.0 |
| 浪潮iMC | Basic Auth | X-IMC-Project |
v0.39.0 |
数据同步机制
graph TD
A[Go应用] --> B[otel-sdk trace.Provider]
B --> C[BatchSpanProcessor]
C --> D[OTLP HTTP Exporter]
D --> E{国产接收网关}
E --> F[天翼云Telemetry]
E --> G[浪潮iMC]
4.3 信创中间件厂商(东方通、普元、金蝶)SDK兼容性测试矩阵构建与自动化验证
为覆盖国产化环境多样性,需建立多维测试矩阵:操作系统(麒麟V10/统信UOS)、JDK版本(OpenJDK 11/21)、中间件SDK版本(东方通TongWeb 7.0.5+、普元Primeton AppServer 8.5.2+、金蝶Apusic 9.0.1+)。
测试维度组合策略
- 每厂商SDK需在3类JDK × 2类OS × 3个Patch级别上交叉验证
- 优先保障LTS版本组合的全通路回归
自动化验证核心流程
# 启动参数标准化注入(以东方通TongSDK为例)
java -Djdk.http.auth.tunneling.disabledSchemes="" \
-Dcom.tongweb.sdk.env=prod \
-cp "tong-sdk-2.3.1.jar:commons-lang3-3.12.0.jar" \
com.tongweb.test.SdkCompatRunner --vendor dtw --os kylinv10 --jdk 11
参数说明:
-Dcom.tongweb.sdk.env=prod强制加载国产化生产配置;--vendor dtw触发东方通专属适配器;--os kylinv10动态加载麒麟V10系统探针模块。
兼容性断言矩阵(部分)
| 厂商 | SDK版本 | JDK11 | JDK21 | UOS20 | 麒麟V10 |
|---|---|---|---|---|---|
| 东方通 | 2.3.1 | ✅ | ⚠️(SSL握手超时) | ✅ | ✅ |
| 普元 | 3.0.4 | ✅ | ✅ | ⚠️(线程池泄漏) | ✅ |
| 金蝶 | 1.8.7 | ⚠️(反射失败) | ✅ | ✅ | ✅ |
graph TD
A[触发CI任务] --> B{读取厂商配置}
B --> C[拉取对应SDK Docker镜像]
C --> D[注入OS/JDK探针]
D --> E[执行统一CompatTestSuite]
E --> F[生成维度级通过率报告]
4.4 政企项目交付中Go SDK灰度发布与热升级机制设计(基于FUSE挂载与atomic swap)
核心设计思想
利用 FUSE 将 SDK 版本抽象为可挂载的虚拟文件系统,结合原子符号链接切换(atomic swap),实现无中断热升级。
关键流程
// 原子切换 SDK 版本入口点
func atomicSwapSDK(newVersion string) error {
oldPath := "/opt/sdk/current"
newPath := fmt.Sprintf("/opt/sdk/v%s", newVersion)
// 创建临时符号链接,再原子替换
tmpLink := "/opt/sdk/current.tmp"
if err := os.Symlink(newPath, tmpLink); err != nil {
return err
}
return os.Rename(tmpLink, oldPath) // POSIX atomic
}
os.Rename 在同一文件系统下保证原子性;/opt/sdk/current 为 FUSE 客户端实际读取路径,挂载点监听其变更并 reload handler。
版本管理策略
| 状态 | 行为 | 触发条件 |
|---|---|---|
active |
全量流量路由 | 符号链接指向该版本 |
staging |
5%灰度流量 + 日志隔离 | 新版本挂载但未激活 |
deprecated |
拒绝新连接,等待长连接退出 | 下线前冷却期(300s) |
升级状态流转
graph TD
A[staging] -->|验证通过| B[active]
B -->|回滚指令| C[deprecated]
C -->|连接清空| D[unmounted]
第五章:未来三年Go语言在信创技术栈中的演进预测
国产化中间件深度集成加速
随着东方通TongWeb、普元Primeton Application Server等国产中间件完成Go SDK 1.0正式版发布,2024年起已有17家政务云平台在API网关层采用Go编写适配模块。某省级政务服务平台将原Java编写的统一身份认证网关重构为Go服务后,QPS从3200提升至9800,内存占用下降63%,其核心改造包括基于golang.org/x/net/http2定制国密SM4加密传输通道,并对接国家密码管理局认证的Bouncy Castle Go封装库(v3.2+)。
信创芯片生态兼容性突破
龙芯3A5000、飞腾D2000与鲲鹏920平台均已通过Go 1.22+官方交叉编译验证。典型落地案例:中国电子CEC某金融监管系统于2023年Q4完成全栈迁移,使用GOOS=linux GOARCH=loong64 CGO_ENABLED=1构建环境,在龙芯3A5000服务器集群上稳定运行TiDB Proxy(Go实现)及自研审计日志采集器,实测CPU缓存命中率提升22%,较x86平台同等配置下GC Pause降低41ms。
安全合规能力内生强化
| 合规要求 | Go原生支持方案 | 落地项目示例 |
|---|---|---|
| 等保2.0三级 | crypto/tls强制SM2证书链校验 |
某央企ERP国产化替代项目(2024.03上线) |
| 密码法合规 | golang.org/x/crypto/sm3标准库集成 |
华为云Stack信创专区审计服务 |
| 日志不可篡改 | hash/crc64+区块链存证Go SDK调用 |
银保监会非现场监管数据上报系统 |
云原生信创基础设施演进
基于OpenEuler 22.03 LTS与KubeEdge v1.12的边缘计算框架中,Go已成为核心组件首选语言。某电力物联网平台部署超2万台边缘节点,其设备管理Agent(纯Go实现)通过github.com/fsnotify/fsnotify监听国产麒麟V10系统安全策略变更,并实时触发os/exec调用自主可控的secctl命令行工具完成权限重置,平均响应延迟
// 示例:国密SSL握手增强代码片段(已用于某省税务云)
func setupSM2TLSConfig() *tls.Config {
cert, err := sm2.ReadCertificate("sm2_cert.pem")
if err != nil {
log.Fatal(err)
}
key, err := sm2.ReadPrivateKey("sm2_key.pem")
if err != nil {
log.Fatal(err)
}
return &tls.Config{
Certificates: []tls.Certificate{{
Certificate: [][]byte{cert.Raw},
PrivateKey: key,
}},
MinVersion: tls.VersionTLS12,
CurvePreferences: []tls.CurveID{tls.CurveP256},
}
}
开发工具链国产化替代进展
VS Code国内发行版(华为CodeArts IDE 2.1)已内置Go语言插件对龙芯架构调试器支持;同时,中科院软件所主导的GoLang-IDE for Kylin项目提供可视化信创合规检查器,可自动识别os/exec未校验路径、net/http未启用HSTS等13类风险模式。截至2024年6月,该工具已在12个部委信息系统开发流程中强制嵌入CI阶段。
生态协同演进趋势
信创工委会《Go语言适配白皮书(2024修订版)》明确将Go列为“基础软件层优先适配语言”,推动gRPC-Go、etcd、Prometheus等关键组件完成银河麒麟V10 SP1、统信UOS V23双系统认证。某国家级工业互联网平台采用Go重构设备接入层后,成功接入航天科工、中船重工等单位的21类国产PLC协议栈,单节点并发连接数突破12万,消息端到端时延稳定控制在17ms以内。
