文章目录

  • 一、Goreplay 介绍
  • 二、Golang环境安装
  • 三、Goreplay 安装
  • 四、Goreplay 使用示例
    • 1、准备 RESTful API 环境
    • 2、捕获服务器一流量保存到本地文件
    • 3、将流量从文件回放到服务器二
    • 4、实时将流量请求打印到终端
    • 5、复制流量实时转发到服务器二
    • 6、压力测试
  • 五、总结

一、Goreplay 介绍

  • Goreplay 是用 Golang 写的一个 HTTP 实时流量复制工具。功能更强大,支持流量的放大、缩小,频率限制,还支持把请求记录到文件,方便回放和分析,也支持和 ElasticSearch 集成,将流量存入 ES 进行实时分析。
  • GoReplay 不是代理,而是监听网络接口上的流量,不需要更改生产基础架构,而是在与服务相同的计算机上运行 GoReplay 守护程序。
  • 特点:简单易用
  • 地址:https://github.com/buger/goreplay
  • stars:14.1k

与 TCPCopy 相比它的架构更简单,只有一个 gor 组件,如下:

只需要在生产服务器上启动一个 gor 进程,它负责所有的工作包括监听、过滤和转发。
它的设计遵循 Unix 设计哲学:一切都是由管道组成的,各种输入将数据复用为输出。

二、Golang环境安装

一 、首先安装Golang及相关依赖环境
在官网上下载安装包或者go的一些中文网站上下载安装包

  1. https://golang.org/dl/
  2. https://studygolang.com/dl

我下载的是: go1.15.5.linux-amd64.tar.gz

二、解压到/usr/local目录下

rm -rf /usr/local/go && tar -C /usr/local -xzf go1.14.3.linux-amd64.tar.gz

三、配置环境变量

# 打开
vim /etc/profile# 添加
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin# 编译生效
source /etc/profile

四、验证

$ go version
[root@vm ~]# go version
go version go1.15.5 linux/amd64

三、Goreplay 安装

从https://github.com/buger/gor/releases 下载最新的 Gor 二进制文件(提供 Windows、Linux x64 和 Mac OS 的预编译二进制文件),也可以自己编译 。

下载二进制包:

[root@vm-1 ~]# curl -L -O https://github.com/buger/goreplay/releases/download/v1.3.1/gor_1.3.1_x64.tar.gz% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100   626  100   626    0     0    741      0 --:--:-- --:--:-- --:--:--   741
100 10.5M  100 10.5M    0     0  3258k      0  0:00:03  0:00:03 --:--:-- 5951k[root@vm-1 ~]# tar xvzf gor_1.3.1_x64.tar.gz
gor


解压缩包后,您可以从当前目录运行 Gor,或者您可能希望将二进制文件复制到您的 PATH(对于 Linux 和 Mac OS,它可以是 /usr/local/bin)。

四、Goreplay 使用示例

1、准备 RESTful API 环境

接口设计:

请求类型 请求路径 功能
Get /person 查询所有人
Post /person/two 事务测试

打包程序分别放到两台服务器 run 起来。

服务器一:

[root@vm-1 ~]# java -jar spirng-boot-demo-0.0.1-SNAPSHOT.jar.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.3.8.RELEASE)2021-08-17 14:19:10.467  WARN 17537 --- [           main] o.s.boot.StartupInfoLogger               : InetAddress.getLocalHost().getHostName() took 10014 milliseconds to respond. Please verify your network configuration.
2021-08-17 14:19:20.494  INFO 17537 --- [           main] com.zuozewei.SpirngbootdemoApplication   : Starting SpirngbootdemoApplication v0.0.1-SNAPSHOT on vm-jmeter with PID 17537 (/root/spirng-boot-demo-0.0.1-SNAPSHOT.jar started by root in /root)
2021-08-17 14:19:20.495  INFO 17537 --- [           main] com.zuozewei.SpirngbootdemoApplication   : The following profiles are active: a
2021-08-17 14:19:22.225  INFO 17537 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-08-17 14:19:22.355  INFO 17537 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 111ms. Found 1 JPA repository interfaces.
2021-08-17 14:19:23.642  INFO 17537 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8082 (http)
2021-08-17 14:19:23.667  INFO 17537 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-08-17 14:19:23.667  INFO 17537 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-08-17 14:19:23.804  INFO 17537 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-08-17 14:19:23.805  INFO 17537 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3179 ms
2021-08-17 14:19:24.314  INFO 17537 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-08-17 14:19:24.479  INFO 17537 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.27.Final
2021-08-17 14:19:25.002  INFO 17537 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-08-17 14:19:25.228  INFO 17537 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-08-17 14:19:25.635  INFO 17537 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2021-08-17 14:19:25.706  INFO 17537 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
2021-08-17 14:19:27.086  INFO 17537 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-08-17 14:19:27.112  INFO 17537 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-08-17 14:19:27.990  WARN 17537 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-08-17 14:19:28.261  INFO 17537 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-08-17 14:19:28.749  INFO 17537 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''
2021-08-17 14:19:28.770  INFO 17537 --- [           main] com.zuozewei.SpirngbootdemoApplication   : Started SpirngbootdemoApplication in 39.553 seconds (JVM running for 40.431)

服务器二:

[root@vm-2 ~]# java -jar spirng-boot-demo-0.0.1-SNAPSHOT.jar.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.3.8.RELEASE)2021-08-17 14:18:34.814  INFO 12775 --- [           main] com.zuozewei.SpirngbootdemoApplication   : Starting SpirngbootdemoApplication v0.0.1-SNAPSHOT on vm-hsyjy-znkzb-vbi-1.novalocal with PID 12775 (/root/spirng-boot-demo-0.0.1-SNAPSHOT.jar started by root in /root)
2021-08-17 14:18:34.820  INFO 12775 --- [           main] com.zuozewei.SpirngbootdemoApplication   : The following profiles are active: a
2021-08-17 14:18:36.293  INFO 12775 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-08-17 14:18:36.419  INFO 12775 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 107ms. Found 1 JPA repository interfaces.
2021-08-17 14:18:37.694  INFO 12775 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8082 (http)
2021-08-17 14:18:37.716  INFO 12775 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-08-17 14:18:37.717  INFO 12775 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-08-17 14:18:37.841  INFO 12775 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-08-17 14:18:37.841  INFO 12775 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2886 ms
2021-08-17 14:18:38.305  INFO 12775 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-08-17 14:18:38.444  INFO 12775 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.27.Final
2021-08-17 14:18:38.864  INFO 12775 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-08-17 14:18:39.119  INFO 12775 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-08-17 14:18:39.556  INFO 12775 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2021-08-17 14:18:39.648  INFO 12775 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
2021-08-17 14:18:41.052  INFO 12775 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-08-17 14:18:41.086  INFO 12775 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-08-17 14:18:42.042  WARN 12775 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-08-17 14:18:42.330  INFO 12775 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-08-17 14:18:42.768  INFO 12775 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''
2021-08-17 14:18:42.786  INFO 12775 --- [           main] com.zuozewei.SpirngbootdemoApplication   : Started SpirngbootdemoApplication in 8.988 seconds (JVM running for 9.939)

2、捕获服务器一流量保存到本地文件

在终端运行这个命令:

#将端口 8082 流量保存到本地的文件
sudo ./gor --input-raw :8082 --output-file=requests.gor
[root@vm-1 ~]# sudo ./gor --input-raw :8082 --output-file=requests.gor
Interface: eth0 . BPF Filter: ((tcp dst port 8082) and (dst host 172.16.106.149 or dst host fe80::f599:6e65:3dc9:b84a))
Interface: lo . BPF Filter: ((tcp dst port 8082) and (dst host 127.0.0.1 or dst host ::1))
Interface: virbr0 . BPF Filter: ((tcp dst port 8082) and (dst host 192.168.124.1))
2021/08/17 14:26:41 [PPID 17654 and PID 17655] Version:1.3.0

注意:

使用–output-file-append 选项可以将捕获流量保存为一个单独的文件
使用sudo并要求输入密码:为了分析网络,Gor 需要只有超级用户才能使用的权限。但是,可以为非 root 用户配置运行Gor 。

在 Postman 上向服务器一发送请求:

我们查看服务一日志:

Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ from person person0_
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into person (age, name, id) values (?, ?, ?)
Hibernate: insert into person (age, name, id) values (?, ?, ?)

可以看到服务已经正常处理了。

我们停掉在服务器一上运行的 Gor,可以看到已经生成了录制的请求文件:

[root@vm-1 ~]# ls -l | grep "requests"
-rw-r----- 1 root    root         300 817 14:33 requests_0.gor

我们看下请求文件的内容:

[root@vm-1 ~]# cat requests_0.gor
1 04481f92ac106afb42ce55ca 1629182282437724065 0
GET /person HTTP/1.1
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Cache-Control: no-cache
Postman-Token: ab405d20-ef93-4ffb-b2f6-a16cf1205e7c
Host: 172.16.106.149:8082
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

3、将流量从文件回放到服务器二

现在是时候将原始流量回放到服务二中了。如果是多个请求并且它们将按照与记录的顺序和时间完全相同的顺序重放。

–output-http 提供第二个服务的 URL

./gor --input-file requests_0.gor --output-http="http://172.16.106.237:8082"
[root@vm-1 ~]./gor --input-file requests_0.gor --output-http="http://172.16.106.237:8082"
2021/08/17 14:42:55 [PPID 12356 and PID 17914] Version:1.3.0
[DEBUG][elapsed 985.792µs]: [INPUT-FILE] FileInput: end of file 'requests_0.gor'

我们看到服务二的日志:

[root@vm-2 ~]# java -jar spirng-boot-demo-0.0.1-SNAPSHOT.jar.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/  ___)| |_)| | | | | || (_| |  ) ) ) )'  |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot ::        (v2.3.8.RELEASE)2021-08-17 14:18:34.814  INFO 12775 --- [           main] com.zuozewei.SpirngbootdemoApplication   : Starting SpirngbootdemoApplication v0.0.1-SNAPSHOT on vm-hsyjy-znkzb-vbi-1.novalocal with PID 12775 (/root/spirng-boot-demo-0.0.1-SNAPSHOT.jar started by root in /root)
......Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ from person person0_

日志说明服务正常响应。

4、实时将流量请求打印到终端

通过命令:

sudo ./gor --input-raw :8082 --output-stdout

此命令其记录到标准控制台输出,请注意,默认情况下 GoReplay 不跟踪响应,您可以使用 --input-raw-track-response 选项启用它们。

[root@vm-1 ~]sudo ./gor --input-raw :8082 --output-stdout
Interface: eth0 . BPF Filter: ((tcp dst port 8082) and (dst host 172.16.106.149 or dst host fe80::f599:6e65:3dc9:b84a))
Interface: lo . BPF Filter: ((tcp dst port 8082) and (dst host 127.0.0.1 or dst host ::1))
Interface: virbr0 . BPF Filter: ((tcp dst port 8082) and (dst host 192.168.124.1))
2021/08/17 14:55:45 [PPID 18060 and PID 18061] Version:1.3.0
1 22ee1f92ac106afb594d205a 1629183362175214036 0
POST /person/two HTTP/1.1
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Cache-Control: no-cache
Postman-Token: 4922ce23-5706-42c5-8a54-ade5d5aee785
Host: 172.16.106.149:8082
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 0

5、复制流量实时转发到服务器二

运行命令:

sudo ./gor --input-raw :8082 --output-http="http://172.16.106.237:8082"
[root@vm-1 ~]# sudo ./gor --input-raw :8082 --output-http="http://172.16.106.237:8082"
Interface: eth0 . BPF Filter: ((tcp dst port 8082) and (dst host 172.16.106.149 or dst host fe80::f599:6e65:3dc9:b84a))
Interface: lo . BPF Filter: ((tcp dst port 8082) and (dst host 127.0.0.1 or dst host ::1))
Interface: virbr0 . BPF Filter: ((tcp dst port 8082) and (dst host 192.168.124.1))
2021/08/17 14:59:49 [PPID 18118 and PID 18119] Version:1.3.0

在服务器二查看日志,.发现流量已经进来了:

Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ from person person0_
Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ from person person0_
Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ from person person0_ where person0_.age=?

6、压力测试

goreplay支持将捕获到的生产实际请求流量减少或者放大重播以用于测试环境的压力测试.压力测试一般针对 Input 流量减少或者放大。

录制的请求文件:

[root@vm-1 ~]# cat requests.gor
1 040f1f92ac106afb7e8d5679 1629183084044026882 0
POST /person/two HTTP/1.1
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Cache-Control: no-cache
Postman-Token: a8600dd1-28c1-4825-b6a2-68c42659942f
Host: 172.16.106.149:8082
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 0
[root@vm-jmeter ~]# cat requests.gor
1 040f1f92ac106afb7e8d5679 1629183084044026882 0
POST /person/two HTTP/1.1
User-Agent: PostmanRuntime/7.28.2
Accept: */*
Cache-Control: no-cache
Postman-Token: a8600dd1-28c1-4825-b6a2-68c42659942f
Host: 172.16.106.149:8082
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 0

我们可以看到主要是两个请求。

运行以下命令,将流量从文件回放到服务器二,并放大两倍:

[root@vm-1 ~]./gor --input-file "requests.gor|200%" --output-http="http://172.16.106.237:8082"
2021/08/17 15:03:58 [PPID 12356 and PID 18187] Version:1.3.0
[DEBUG][elapsed 1.361742ms]: [INPUT-FILE] FileInput: end of file 'requests.gor'

我们查看下服务二日志的处理情况:

Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into person (age, name, id) values (?, ?, ?)
Hibernate: insert into person (age, name, id) values (?, ?, ?)

我们可以看到服务处理了四个请求。​

注意,当然也支持请求流量 10%,20% 等缩小。

五、总结

今天简单介绍 Gor的常见玩法,事实上远不止上述提到的这些,更多的玩法有时间再写。

文件源码:

  • https://github.com/zuozewei/blog-example/tree/master/Performance-testing/04-full-link/springboot-demo

相关系列:

  • 性能工具之常见流量复制工具
  • 流量回放工具之 goreplay 安装及初级使用
  • 流量回放工具之 goreplay 核心源码分析(VIP)
  • 流量回放工具之 GoReplay output-http-stats(HTTP请求统计) 源码分析
  • 流量回放工具之GoReplay output-http 源码分析

流量回放工具之 Goreplay 安装及初级使用相关推荐

  1. 流量回放工具:goreplay实战

    相信做性能测试的小伙伴们一定听说过流量复制回放,没听说过也没关系,我们大都是在性能测试环境完成压测任务出具性能测试报告, 但是实际生产环境的接口压力流量往往和我们在性能测试环境预估的情况不完全一致,甚 ...

  2. 性能工具之 Goreplay 安装及入门使用

    性能工具之 Goreplay 安装及入门使用 1.Goreplay 介绍 Goreplay 是用 Golang 写的一个 HTTP 实时流量复制工具.功能更强大,支持流量的放大.缩小,频率限制,还支持 ...

  3. Doom流量回放工具导致的测试环境服务接口无响应的排查过程

    Doom流量回放工具导致的测试环境服务接口无响应的排查过程 现象描述: a)部分接口(A组接口)无响应 b)部分接口(B组接口)正常响应 c)还有一部分接口(C组接口),场景1无响应,场景2正常响应 ...

  4. Linux网络实时流量监测工具iftop的安装使用

    概述:网络管理是基础运维中一个很重要的工作,在看似平静的网络运行中,其实暗流汹涌,要保证业务系统稳定运行,网络运维者必须要了解网络的流量状态.各个网段的使用情形,带宽的利用率.网络是否存在瓶颈等,同时 ...

  5. 流量回放工具gor使用经验

    简介: 测试 HTTP 服务,为了覆盖更多的场景,可以考虑录制线上流量,在测试环境进行重放.之前用 tcpcopy 比较多,最近遇到一些需求,需要在 HTTP 层做一些过滤,例如只录制指定 URL 的 ...

  6. netflow流量分析工具 linux,Linux安装Nfdump和Nfsen图形界面分析netflow数据

    # 安装 rrdtool 及所需组件: yum install -y perl-rrdtool rrdtool rrdtool-devel rrdutils flex byacc # 安装 rrdto ...

  7. 流量回放开源代码Java_流量回放框架 jvm-sandbox-repeater 的实践

    一. 前言 你是否和我一样遇到过以下的问题? 1)服务重构,一堆接口需要回归,让人头疼 2)每次迭代,都要花很多精力来进行回归测试 3)线上 bug,线下复现不了 4)接口自动化用例写辛苦,维护更辛苦 ...

  8. 流量回放框架jvm-sandbox-repeater的实践

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net 一. 前言 你是否和我一样遇到过以下的问题? 1)服 ...

  9. java化测试神器-流量回放平台

    # java化测试神器-流量回放平台 作者:佳晖,荣荣 文章结构 基本介绍 使用流程 实现方案 总结 基本介绍 背景 目前公司正在进行php java化迁移工作. Java化测试本质上是一次回归工作. ...

最新文章

  1. 2020年人工神经网络第二次作业-参考答案第七题
  2. C#中的平台调用(P/Invoke)
  3. android 实现显示电量,Android开发:显示电池电量
  4. python数据分析-数据准备
  5. 记一次小型生产事故 | BeyondComper跨编码方式复制文件内容
  6. 山西台达plc可编程控制器_可编程控制器2(PLC)控制原理
  7. Linux CPU占用率监控工具小结
  8. java应用程序做授权_java-为我的Web应用程序编写授权过滤器(JSF ...
  9. 茅侃侃,80后技术人与你同在 | 一周业界事
  10. redis运行redis-server.exe错误
  11. Android Multimedia框架总结(二十八)NuPlayer到OMX过程
  12. 基于WordNet的英文同义词、近义词相似度评估及代码实现
  13. 一个完整机器学习项目流程总结
  14. 免费搜题网课答案微信公众号系统
  15. Libra最后的命运
  16. android 10.0 在系统源码下生成jks系统签名文件
  17. Python hasattr()
  18. 鸿蒙系统大文件夹怎么调整大小,win7系统打开窗口太大或太小的调整方法
  19. Numpy 100道练习题+常用知识点
  20. 每日分享html之两个input搜索框、两个button按钮、一个logo效果

热门文章

  1. 杭州python编程培训晚班
  2. 小区业主入户安检小程序开发
  3. Android camera2 实现估算眼睛到屏幕的距离 人脸识别 护眼实验室
  4. 人工智能ai用什么编程语言_用于AI开发的6种最佳编程语言
  5. C语言之数组的定义及其使用方法
  6. 一个大二计算机学生的学期总结
  7. 源码该如何加密:个人方案分享
  8. Android(三十二):AlertDialog 对话弹窗
  9. PS图片操作简单方法:
  10. python中使用schedule模块定时执行任务