高频交易下证券公司交易系统的性能优化
高频交易下证券公司交易系统的性能优化
talkwithtrend
talkwithtrend.com社区(即twt社区)官方公众号,持续发布优秀社区原创内容。内容深度服务企业内各方向的架构师、运维主管、开发和运维工程师等IT专业岗位人群,让您时刻和国内企业IT同行保持信息同步。
【作者】周尤珠, 就职于海通证券股份有限公司。从业近20年,一直负责券商经纪业务侧交易系统的管理及研发工作,目前负责海通新一代核心交易系统的建设。在交易技术前沿等期刊上发表核心交易系统相关论文数篇,获得专利1项。
第一章 概述
交易系统性能优化是当前国内金融市场中一个备受关注的话题。近年来,随着T+0交易品种陆续上市,以及北交所、广期所的成立挂牌,金融交易市场机会不断涌现。在这个竞争激烈的环境下,如何在最短的时间内获取到最新的股票、期权、期货及相关的行情信息,并且能够以最快的速度向交易所提交订单请求,是市场竞争的重要方向。
对于一次委托来说,订单全链路耗时即投资者的交易订单从订单形成系统发至经纪公司订单处理系统经过其处理确认后发往交易所及交易所确认报单后按原路径返回至订单形成系统的往返整体链路的耗时。而对于高频交易来说,投资者除了要求订单全链路耗时不断提速外,同时也会对分笔行情的获取有极高的要求,因此整个高频交易体系内的调优主要涵盖网络链路、订单形成系统、订单处理系统、交易所报盘网关、交易所内部系统、行情(接收)、分析行情(策略部分)等各环节。分析各环节的耗时占比及调优性价比权衡得出最适合当下的方案。
各家应用场景各有不同,本文针对基础软硬件和网络简单介绍下通用方案供各位参考:
第一,找寻影响因子,应当建立稳定、高速的全链路数据度量通道,保证实时、准确地获取网络快慢、系统优劣的度量数据。全链路度量是对高频交易系统整个交易流程进行全方位的度量和评估。通过全链路度量,可以精确地评估每个环节的效率和时延,找出影响系统性能的瓶颈,并针对性地进行优化和改进。
第二,单元优选更换,使用高性能的硬件设备,能够在底层搭好框架,保证提供高算力,完成订单匹配,减少交易时延,提高交易执行的效率和成功率。
第二章 常见问题
整体性能优化包含但不限于下述步骤:
1)影响因子评估;
2)瓶颈观测及分析;
3)单元调优;
4)系统级优化;
5)持续监控及改进。
通常存在以下常见问题:
找寻影响因子
-
问题定位难:交易环境复杂,交易链条长,无法精准定位系统性能问题;
-
度量精度要求高:极速行情、交易软硬件频繁更新优化,常规测试方法无法达到精度要求,对比测试大费周章;
-
偶发问题难觉察:日常测试无法发现交易系统偶发问题(抖动、异常响应速度)。
单元优选更换
-
高性能服务器选择:高频交易系统需要处理大量的市场行情数据、历史数据和实时数据,并进行复杂的计算和分析。如何选择合适的高性能CPU和内存的服务器是至关重要的。高频率的多核处理器和大容量的内存可以快速处理数据,加速算法模型的计算和决策生成。
-
低延时网卡选择:高频交易系统需要及时获取和传输行情数据,而且通常需要与多个交易所和数据源连接。因此,选择具有高带宽和低延迟的网卡是必要的。
-
高稳定低延时交换机选择:高频交易系统通常需要持续运行,并承受大规模的数据处理和交易流量。因此,选择具有高可靠性和低延时的交换机可以提高系统的稳定性和可靠性。
系统调优观察
-
调优方案定夺:除了硬件层面优化,系统层面的优化包括且不限制于进程调用、函数处理等,在开销及时延消耗比较大的函数栈中,通过进行定制化工具开发,实施埋点等操作,从而进行代码级性能瓶颈分析,并助力给出针对性的调优方案
-
持续观察分析:在调优手段覆盖之后,基于目前券商大多数系统环境,即使在某一次调优后达到了不错的数据,但是由于负载均衡、内核污染等等不可避的问题存在,单次调优无法达到应有效果,所以持续分析是不可缺少的一环。
第三章 优化思路
找寻影响因子——
度量
极速高频交易环境中,需要采用最快的网络设备进行组网,并且要对全链路节点的处理时延、流量、抖动等性能指标进行高精准统计与展示,帮助运维人员对应用系统性能异常和故障做出精准快速定位。
行情链路包括:行情网关,行情解码,行情转发,客户端,网络设备等;
交易链路包括:客户策略,交易系统,报盘网关,网络设备、防火墙等。
现有业务分析及监控平台主要采用系统内置分析模块,但只能分析单节点性能,不能分析全链路端到端性能;且软件操作系统打点,时间精度抖动较大,准确性不足。
上图为一种全链路的高精度度量方案,此方案通过将网络流量旁路导出至高精准时间戳设备,在数据包尾部添加上可识别的时间戳标识,并实时进行流量解析计算,计算精度为皮秒级别,可以支持全链路时延精准度量。
单元优选更换——
匹配
交易链的不同参与者对于设备的要求会有所不同,从底层链路、网络的选择上,都需要选择合适匹配的参与单元,而作为关键点的交易系统和宿主机,在满足高性能低延时的同时,还需考虑载体、温度、功耗等一一来进行选型,并逐步建立测评选型基准。交易系统不光需要追求极低的延时,更重要的是保持整体稳定,稳定即可预期,可掌控,如果相对波动较大,就无法预测报单策略的有效性。
系统调优观察——
定性
机器从出厂之后,就会有相关参数,而通过PCIE和速率、IO和负载、字节和网速等等,会计算出一个理想数值,但现实情况中往往达不到理想值。此时则需在整体系统中,对当前CPU、IO、Memory等进行密集性、内存负载、IO基准等测试,如性能监控下,可采用PCP测试;系统追踪中,运用Pcef;针对于系统调用,用Toolkit进行跟踪等等。如此以来,将将硬件、系统、应用等进行一连串调优,再根据每次调优后的数据计算出基线和饱和率,审视工作流。
在审视工作流完成基数标定之后,OS层承上启下,单点定性后往往在某次调优后牵一发而动全身。基于操作系统层面实现交易系统优化往往非常有效,比修改应用程序、改善硬件环境等问题解决更彻底、整体TCO更优。这个时候,针对于OS层面,往往需要确认四件事情。
1.命令集:在调优OS层面时,首先需要确认使用的命令集。不同的硬件架构和处理器可能支持不同的命令集,例如x86、x86-64、ARM等。了解命令集对于确定可用的优化选项以及应用程序的性能影响非常重要。
2.
BIOS设置:BIOS(基本输入/输出系统)是在计算机启动过程中加载的固件,它负责初始化硬件并传递控制权给操作系统。在调优OS层面时,需要确认BIOS设置是否合理。例如,检查BIOS中的电源管理选项、内存配置、硬件虚拟化支持等设置,以确保它们与应用程序的性能需求相匹配。
3.OS本身:操作系统本身也可能对系统性能产生影响。确保操作系统已经进行了必要的优化和调整,例如启用了适当的内核参数、关闭了不必要的服务、设置了正确的文件系统选项等。此外,还可以考虑更新操作系统补丁和驱动程序,以修复可能存在的性能问题。
4.负载容量规划:在调优OS层面时,需要对负载容量进行规划和评估。这包括确定系统的预期负载和性能需求,以便为其分配足够的资源。可以考虑调整CPU调度策略、内存管理设置、文件系统缓存大小等,以优化系统的性能和响应能力。
第四章 性能天梯
高频交易端到端链路从架构上可分为应用交付层、支撑环境层、操作系统层、硬件设备层和基础设施层。应用交付层主要是交易应用程序和算法,支撑环境层包括了消息中间件、程序加速软件等环境软件,基础设施层主要由机房基础设施组成。端到端整体时延可以理解为证券公司从接收交易所行情入口到报盘至交易所间各个节点的延时之和,其中包括了行情系统、交易系统、网络设备、服务器网卡、光纤传输等等环节,各环节目前的时延量级如下:
-
毫秒(10-3秒)级别:运营商专线
-
百微秒(10-6秒)级别:交易系统、行情系统、交易网关等
-
微秒(10-6秒)级别: FPGA系统、服务器网卡
-
百纳秒(10-9秒)级别:低延时网络设备
-
纳秒(10-9秒)级别:光纤、一层交换机
第五章 调优技术
在选用合适的硬件之后,仅仅完成了初始阶段。怎么达到最佳性能,在目前的阶段还是没有尽头的。而在低延迟领域,如高频系统或实时媒体系统,大多要求服务器在10微秒以下提供一致的系统响应。这就需要硬件、操作系统、应用、网络等领域进行调优以达到这一要求。本章节将主要针对硬件及操作系统层面的调优技术做一些探索和分享。
硬件配置
要实现微秒级的低延迟,首先需要了解被测系统的硬件配置。影响时延的重要因素包括核心数、每个核心的执行线程数、插槽数、NUMA节点数、CPU和内存在NUMA拓扑中的排列,以及NUMA节点中的缓存拓扑。Linux系统可以时延lscpu命令,对硬件拓扑情况进行查看。
从上图,我们知道这是一台双路CPU的服务,总共安装了两颗CPU,Numa节点数为2等信息。请注意,如果应用系统所需线程数较少,单路CPU的服务器也是不错选择,它会减少一些槽位间通信的复杂性。
为了获得最佳的响应时间,需要对系统拓扑进行优化,其中内存需要均匀的在NUMA节点上进行安装,并尽量最大化使用本地内存。关键应用需要运行在隔离CPU上,并且与Numa节点、PCIE网卡在系统拓扑上保持一致,以获得最优的数据路径。
-
Numa和内存
以我们常用的双路服务器为例, Numa架构大致如下。
我们可以通过numactl来查看numa节点信息
CPU远程访问Numa节点时,距离毕竟长,性能会受到极大影响,低时延应用程序需要避免跨Numa的远程内存访问,从下面的命令,我也可以看出远程访问Numa的性能远低于本地访问。
-
NUMA内存平衡
Linux支持基于自动NUMA内存平衡和手动迁移内存,但在NUMA节点之间迁移内存页面将导致内存的TLB被清除和页面故障,从而影响程序性能。
还可以禁用用户空间的numad服务,关闭NUMA内存平衡。
绑定程序在一个核上运行,有两种方法:taskset和sched_setaffinity,其中sched_setaffinity是程序代码对绑核的实现,我们主要介绍通过taskset进行绑核。
CPU亲和性,是指在SMP结构下,能够将一个或多个进程绑定到一个或多个处理器上运行。
taskset
-c -p <pid>
top -p
<uid>
该例会将PID为31693的进程绑定到1-3核上运行。
-
屏蔽硬中断(硬盘、网卡)
中断源(IRQ)向CPU Core发送中断,CPU
Core调用中断处理程序对中断进程处理。我们可以通过改写/proc/irq/*/smp_affinity文件,避免中断源(IRQ)向某些CPU Core发送中断。该方法对硬盘、网卡等设备引起的硬中断有效。
- 第二列开始表示某CPU内核被多少次中断。
-
SMP_AFFINITY
echo
1-2 > /proc/irq/60/smp_affinity_list
-
内核参数
echo 0
> /proc/sys/kernel/watchdog
echo
10 > /proc/sys/vm/swappiness
echo
10 > /proc/sys/vm/dirty_ratio
echo 3
> /proc/sys/vm/dirty_background_ratio
echo
24000000 > /proc/sys/kernel/sched_latency_ns
echo
10000000 > /proc/sys/kernel/sched_min_granularity_ns
echo
-1 > /proc/sys/kernel/sched_rt_runtime_us
以秒为单位的更新虚拟内存统计信息的间隔。默认值是 1 秒,这导致每秒进行信息统计。将其更改为 1000 秒可以避免这些中断,至少延迟了 16 分钟。
echo
performance > /sys/devices/system/cpu/cpu57/cpufreq/scaling_governor
操作系统配置
BIOS配置
-
CPU安全漏洞
近年频繁暴露出CPU漏洞,比如MDS、Zombieload、Spectre、Meltdown、L1TF在Intel x86微处理器中发现的安全漏洞,它们都利用了微处理器的预测执行(speculative
execution)功能来窃取敏感数据。这些漏洞都需要在固件和内核层面进行修补,但这会导致性能的下降。
MDS(Microarchitectural Data Sampling,微架构数据采样)是一组在2018年发现的漏洞,它们可以通过读取处理器内部的数据缓冲区来泄露跨越保护边界的数据。
Zombieload是MDS的一种变体,它可以通过监视处理器执行的指令来获取敏感数据,例如密码、密钥、浏览历史等。
Spectre(幽灵)是一组在2018年初公开的漏洞,它们可以通过操纵处理器的分支预测(branch
prediction)功能来迫使目标程序执行非预期的指令,并从其缓存中读取敏感数据。
Meltdown(熔断)是一组与Spectre类似的漏洞,它们可以通过利用处理器的乱序执行(out-of-order
execution)功能来绕过内存隔离机制,并从内核或其他进程中读取敏感数据。
L1TF(L1 Terminal Fault,L1终端故障)是一组在2018年中公开的漏洞,它们可以通过访问L1缓存中的无效或不可访问的物理地址来泄露跨越保护边界的数据。L1TF包括以下几种变体:Foreshadow, Foreshadow-NG (OS,
SMM, VMM)。
这些漏洞都对Intel x86微处理器造成了严重的威胁,尤其是使用超线程技术(Hyper-Threading)的处理器。为了防止这些漏洞的攻击,用户需要更新系统和固件,并可能需要关闭超线程技术。但这些措施都会影响处理器的性能,不同的工作负载会有不同程度的下降。
在高频交易领域,特别是针对券商行情、交易系统、报盘这些应用,因为部署环境处于内网,安全环境比较好,可以通过内核参数mitigations=off来关闭缓解措施,以提升系统性能。
-
屏蔽软中断(Local Timer Interrupt)
Linux的scheduler
time slice是通过LOC实现的,如果我们让一个线程独占一个CPU Core,就不需要scheduler在这个CPU Core上切换进程。可以通过isolcpus系统启动选项隔离一些核,让他们只能被绑定的线程使用。同时,我们还可以启用“adaptive-ticks”模式,达到减少独占线程收到LOC频率的效果,这可以通过nohz_full和rcu_nocbs启动选项实现。
假设令6-8三个核心屏蔽软中断,我们需要在系统启动选项中加入:
``
`text
nohz=on nohz_full=6-8 rcu_nocbs=6-8
`
``
进入adaptive-ticks模式后,如果CPU Core上的running task只有一个时,系统向其发送的LOC频率会显著降低,但LOC不能被完全屏蔽,系统内核的一些操作比如计算CPU负载等仍然需要周期性的LOC。
-
关闭交换分区
swapoff
-a
-
关闭透明大页
通过提供内核命令行参数transparent_hugepage=never或运行以下命令来禁用透明大页支持:
echo never >
/sys/kernel
/mm/transparent
_hugepage/enabled
-
同页合并
Linux内核同页合并(KSM)是一项功能,用于去重包含相同数据的内存页面。合并过程需要锁定页面表并清除TLB,从而导致内存访问延迟不可预测。KSM仅对已经通过madvise(...MADV_MERGEABLE)选择加入同页合并的内存页面进行操作。如果需要,可以通过运行以下命令在系统范围内禁用KSM:
echo
0
>
/sys/kernel
/mm/ksm
/run
-
使用大页
应用程序访问的页面在TLB中缺失时,内存管理单元(MMU)遍历整个页表,会有极大的性能开销。通过使用2MB或1GB的大页面,可以显著的减少TLB未命中次数。
我们可以使用perf工具监控TLB未命中情况:
# perf stat -e ’dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses’ -a --timeout 10000
Performance counter stats
for
’system wide’
:
10,525,620 dTLB-loads
2,964,792 dTLB-load-misses
# 所有dTLB缓存命中的28.17%
1,998,243 iTLB-loads
1,068,635 iTLB-load-misses
# 所有iTLB缓存命中的53.48%
10.002451754秒的已用时间
上述输出显示了未命中的数据加载(dTLB)和指令加载(iTLB)的比例。我们观察到大量的TLB未命中,应考虑使用大页面以减少TLB未命中次数。
-
关闭服务
关闭一些多余服务,减少系统扰动
#!/bin/sh
for
SERVICE
in
avahi-daemon.service crond.service dnsmasq.service
firewalld.service lvm2-monitor.service postfix.service
rpcgssd.service rpcidmapd.service rpcsvcgssd.service
wpa_supplicant.service
do
systemctl
disable
$SERVICE
systemctl stop
$SERVICE
done
```
应用配置
-
屏蔽Work queue
workqueue是自kernel2.6引入的一种任务执行机制,和softirq,tasklet并称下半部(bottom half)三剑客。workqueue在进程上下文异步执行任务,能够进行睡眠。可以通过改写/sys/devices/virtual/workqueue/*/cpumask文件实现屏蔽Work queue的软中断。
/sys/devices/virtual/workqueue/cpumask文件中记录了全局的cpumask,可以影响所有的workqueue。比如我们只希望CPU0和CPU3来执行workqueue,我们计算初CPU0和CPU3的cpumask为0x9(二级制:10001)
echo 9
/sys/devices/virtual/workqueue/cpumask
网卡配置
-
检查网卡Numa信息
根据网卡的numa_node设置对应的RPS队列,变为网卡的中断绑定
cat
/sys/class/net/ens3f1/device/numa_node
-
Kernal Bypass
Kernel Bypass技术在高频交易系统中有大量应用。在不变更程序代码的角度来说,目前可用的解决方案有:Solarflare onl oad、Mellanox VMA和Exasock三种。Kernel Bypass的优点就是实现了用户态网络协议栈(User-space Networking)允许应用程序在用户态中运行网络协议栈,避免了数据包在Linux内核中的传输过程,以及涉及内核态的切入切出,还有零Copy等技术的使用,极大的提升效率,降低传输时延。
-
Onload
Solarflare onl oad是一种由Solarflare Communications开发的网络加速技术,旨在提高服务器和数据中心网络性能,降低网络通信的延迟和CPU负载。这项技术主要用于高性能计算(HPC)、云计算和金融领域等需要低延迟和高吞吐量网络连接的应用程序。onload无需对应用程序进行修改就可实现加速效果。
onload
sockperf server -i 11.4.3.3
-
VMA
Mellanox VMA(Virtual
Memory Acceleration)是一种由Mellanox Technologies(现在是NVIDIA的一部分)开发的网络加速技术。它旨在提高网络性能,减少网络传输的CPU负载,并降低延迟。VMA无需对应用程序进行修改就可实现加速效果。
LD_PRELOAD=libvma.so
VMA_SPEC=latency sockperf server -i 11.4.3.3
-
Exasock
思科Nexus SmartNIC(前身为ExaNIC)Kernal Bypass方案,无需对应用程序进行修改。通过简单的在应用程序前加exasock来执行。
exasock
nc -u -l 1234
Kernal Bypass在降低网络时延的同时,也带来了一系列的问题,他们一般都会对阻塞select(), poll(), epoll_wait(), recv(), read() 和 accept()这些调用来等待数据到来,会较多占用CPU运行时间,导致这段时间可用CPU数变少,如果应用程序的线程数大于可用CPU资源数时,就会存在CPU资源竞争,导致性能下降。所以是否应用Kernel Bypass方案,要根据实际程序的运行情况来确定。
网络配置
证券交易网络通信通常具有一个非常明显的特征:Microburst。即从宏观结构上来看,平均每秒流量非常小,但是缩放到毫秒级刻度,则会出现链路使用率几乎满载的情况,如下图所示:
交易数据从局域网内部一台主机传输到另一台主机,沿途会经历几种不同类型的时延:丢包时延(Packet
Drop Delay)、排队时延(Queuing Delay)、路由交换转发时延(Switch
Processing Delay)、传输时延(Propagation Delay)和串行化时延(Serialization
Delay)。其中丢包时延、排队时延、串行化时延都和交换机端口带宽和端口缓存直接相关,而传输时延一般受距离影响较大,路由交换转发时延则是交换机设备的转发耗时。因此,使用更低时延的交换机和更大的带宽通常可以有效缓解延迟问题。
极致的网络环境中可以适当选择一层或FPGA交换机来做到极低时延的网络转发。一层交换机的实现原理是通过复制电平高低信号来实现信号的快速复制传播,并且能够将电信号进行增强及平稳处理,使得直通转发时延低至5ns以内。较适用于高速行情分发场景。FPGA交换机可以将同一用户的策略服务器订单上报后进行汇聚输出,时延低至40ns以内;也针对不同用户的策略服务器连接,可以通过VLAN进行划分隔离。
调优工具
调优工具跟踪机制
(点击图片可放大)
常用工具
-
内核版本低于4.1
以 Centos7 系统为例, 其依赖 3.10.0 内核版本, 这就决定了我们只能通过 perf_event, ftrace/utrace 和 systemtap 的方式进行系统调试. 在实际使用的时候我们需要考虑不同的需求使用不同的工具, 如下所示为简单的总结:
(点击图片可放大)
如果 Redhat/Centos 7 内核高于 3.10.0-940.el7.x86_64, 可以酌情使用基于 eBPF 的 bcc-tools 工具。
-
内核版本高于4.1
高于 4.1+ 版本的系统可以直接通过 eBPF 获取想要调试的信息。当然也可以继续使用 frace, systemtap 等工具
工具示意
在当前的 Linux 发行版中,perf 和 strace 是两个得到广泛支持的分析工具。它们提供了丰富的功能,用于诊断和优化系统性能问题,它们安装最为便捷,同时对于环境的依赖较小,输出信息可读性也比较好。
-
perf 进行信息采集示例
1. 通过 perf stat 命令可以统计程序的性能指标例如指令数、周期数、缓存命中率等。例如,要统计当前系统的Local
Timer中断情况,同时安装每个CPU进行汇总:
Perf stat –e ‘irq_vectors:local_timer_entry’
-a -A --timeout 30000
2. 通过perf record命令可以记录程序的性能事件,然后使用 `perf report` 命令来分析记录的数据。例如,要记录驱动程序接受网络数据包事件:
perf record -e
‘net:netif_recevie_skb’ -a
记录perf.data数据以后还可以通过perf report进行查看
3. perf trace 是 perf 工具套件的一部分,用于跟踪系统上的函数调用和事件流,以便分析应用程序和系统的行为。它的主要作用是提供更详细的系统跟踪和分析,以帮助识别性能问题和故障排除。
例如:我们可以用perf record -s –p 3329来记录进程系统调用的汇总信息,通过汇总信息我们可以初步评估进程主要的系统调用情况。
-
strace`进行信息采集
使用 `strace` 来跟踪程序的系统调用。例如,要跟踪某一进程的系统调用,可以运行以下命令:
strace –tt -T -yy -ff –p 8661
通过输出的信息,我们可以跟踪某一进程的recvfrom和sendto的系统调用。
第六章 成果及效益
通过探索系统整体调优方案,我们获得了以下方面的收益:
1)从系统性能提升的优化目标而言,实现了4.8GHz服务器在非实时普通内核上,系统定时的抖动误差从优化前的30us,降低到4us以内;2.6GHz服务器的系统定时抖动误差也从优化前的80us,降低到10us以内。
第七章 总结和展望
总结
对投资者和经纪公司来说,交易的延时无疑至关重要,本文通过关注找寻全链路各环节的影响因子、单元优选更换、系统调优观察几个维度,对系统优化提出了体系化的方法思路,并取得了一定的成果,对我司有效支持机构高频客户对交易全链路稳定和低延时的极致需求,全面提升公司交易服务能力有指导性意义。
基于操作系统层实现交易系统性能优化,需要对Linux内核等深度掌握。券商同行可以一方面持续提高自己的队伍在这方面的能力,同时也可考虑采用红帽等专业厂商的调优服务来为己所用。
展望
我们此次主要针对操作系统和网络层面进行了优化探索,但Linux内核、CPU知识体系庞大,仍需持续深入学习研究。包括上层应用系统的架构及代码均可持续优化。
同时我们也要意识到,速度虽然重要但不是全部,目前交易系统的军备竞赛已经上升到微秒级,去除交易所侧在百微甚至几十微的也不在少数,而这种情况下一个网络抖动、开盘的脉冲干扰或者交易所侧的其他不确定因素可能直接覆盖了其他环节的耗时。因此我们同样需要做好稳定性的保障。
券商作为经纪业务服务商,如何利用各方面资源服务好投资者,留住投资者个人认为更是我们的核心竞争力。
点击文末 阅读原文 ,可以到原文下留言交流 觉得本文有用,请 转发 或点击 赏 ,让更多同行看到
资料/文章推荐:
-
Linux系统性能优化的7个实战经验
欢迎关注社区以下 “系统运维”技术主题 ,将会不断更新优质资料、文章。地址:
http://www.talkwithtrend.com/Topic/112795
下载 twt 社区客户端 APP
长按识别二维码即可下载
或到应用商店搜索“twt”
长按二维码关注公众号
*本公众号所发布内容仅代表作者观点,不代表社区立场
-
2023年血糖新标准公布,不是3.9-6.1,快来看看你的血糖正常吗? 2023-02-07
-
2023年各省最新电价一览!8省中午执行谷段电价! 2023-01-03
-
GB 55009-2021《燃气工程项目规范》(含条文说明),2022年1月1日起实施 2021-11-07
-
PPT导出高分辨率图片的四种方法 2022-09-22
-
2023年最新!国家电网27家省级电力公司负责人大盘点 2023-03-14
-
全国消防救援总队主官及简历(2023.2) 2023-02-10
-
盘点 l 中国石油大庆油田现任领导班子 2023-02-28
-
我们的前辈!历届全国工程勘察设计大师完整名单! 2022-11-18
-
关于某送变电公司“4·22”人身死亡事故的快报 2022-04-26
