首页
关于道锋
工具
友情链接
公告栏
麟图图床
麟云文件
麟云KMS
麟云工具
麟云证书管理
Search
1
使用ReDroid打造自己的云手机
3,694 阅读
2
Cloudflare SAAS 接入自选教程
2,236 阅读
3
兽装曲腿制作文档
1,999 阅读
4
Frpc使用XTCP不通过服务器传输
1,870 阅读
5
CloudFront CDN配置教程
1,229 阅读
默认
科学
热力学
Furry
小说
星河野望
手工制作
道具制作
音影
图像工具
计算机
渗透
硬件
编程
网络
记录
AI人工智能
CVE
软件工具
装机教程
C/C++
C#
Go
HTML5+JS+CSS
JAVA
Lua
Rust
PHP
Python2/3
Nodejs
编译
C/C++学习日志
Golang学习日志
Rust开发技巧
Rust学习日志
Rust开发教程
Nonebot2机器人框架
python开发教程
python开发技巧
Python学习日志
ai绘画
电子电路
电路设计
PCB打板
制作实战
无线电
摄影
运维
WEB
KVM云计算
docker
Ansible
代码管理
Kubernetes
Linux
MySQL
shell
集群
Zabbix
Prometheus
数据安全
Redis
istio
ELK
Nginx
Apache
Tomcat
Elasticsearch
Logstash
Kibana
测评
服务器
登录
Search
标签搜索
开源
源码
教程
服务器
环境搭建
摄影
rustlang
Rust
VS CODE
v2ray
bbr
加速
网络优化
拥塞控制
CloudFront教程
CF教程
AWS教程
CloudFront接入
Frpc
Frps
道锋潜鳞
累计撰写
443
篇文章
累计收到
124
条评论
首页
栏目
默认
科学
热力学
Furry
小说
星河野望
手工制作
道具制作
音影
图像工具
计算机
渗透
硬件
编程
网络
记录
AI人工智能
CVE
软件工具
装机教程
C/C++
C#
Go
HTML5+JS+CSS
JAVA
Lua
Rust
PHP
Python2/3
Nodejs
编译
C/C++学习日志
Golang学习日志
Rust开发技巧
Rust学习日志
Rust开发教程
Nonebot2机器人框架
python开发教程
python开发技巧
Python学习日志
ai绘画
电子电路
电路设计
PCB打板
制作实战
无线电
摄影
运维
WEB
KVM云计算
docker
Ansible
代码管理
Kubernetes
Linux
MySQL
shell
集群
Zabbix
Prometheus
数据安全
Redis
istio
ELK
Nginx
Apache
Tomcat
Elasticsearch
Logstash
Kibana
测评
服务器
页面
关于道锋
工具
友情链接
公告栏
友人
PCD-01’s Blog
iMin博客
特资啦!个人资源分享站
黎洛云综合门户网站
三石的记录
咬一口激动的鱼
中二病晚期の物語
奇梦博客
布丁の小窝
道麟笔记
迷失的小K
koto's Site
Abyss-博客
西西のBlog
锐冰龙小站
Nick的琐碎日常
渣渣120
麟图图床
麟云文件
麟云KMS
麟云工具
麟云证书管理
搜索到
361
篇与
的结果
2021-10-12
V2Ray 搭建教程以及一键安装脚本
V2Ray 是一个网络转发程序,支持 TCP、mKCP、WebSocket 这3种底层传输协议,支持 HTTP、Socks、Shadowsocks、VMess 这4种内容传输协议(HTTP 只支持传入),并且有完整的 TLS 实现,是一个非常强大的平台。V2Ray 简介官网:https://www.v2ray.comProject VProject V 是一个工具集合,它可以帮助你打造专属的基础通信网络。Project V 的核心工具称为 V2Ray,其主要负责网络协议和功能的实现,与其它 Project V 通信。V2Ray 可以单独运行,也可以和其它工具配合,以提供简便的操作流程。主要特性多入口多出口: 一个 V2Ray 进程可并发支持多个入站和出站协议,每个协议可独立工作。可定制化路由: 入站流量可按配置由不同的出口发出。轻松实现按区域或按域名分流,以达到最优的网络性能。多协议支持: V2Ray 可同时开启多个协议支持,包括 Socks、HTTP、Shadowsocks、VMess 等。每个协议可单独设置传输载体,比如 TCP、mKCP、WebSocket 等。隐蔽性: V2Ray 的节点可以伪装成正常的网站(HTTPS),将其流量与正常的网页流量混淆,以避开第三方干扰。反向代理: 通用的反向代理支持,可实现内网穿透功能。多平台支持: 原生支持所有常见平台,如 Windows、Mac OS、Linux,并已有第三方支持移动平台。安装 V2Ray在开始安装之前,安装一些必要的软件:Ubuntu/Debian 系统: apt-get update -y && apt-get install curl -yCentOS 系统: yum update -y && yum install curl -y为了简化安装,我们使用一键安装脚本,使用现成的一键安装脚本,使用 root 用户输入下面命令安装:bash <(curl -s -L https://git.io/v2ray.sh)然后选择安装,即是输入 1 回车选择传输协议,如果没有特别的需求,使用默认的 TCP 传输协议即可,直接回车选择端口,如果没有特别的需求,使用默认的端口即可,直接回车是否屏蔽广告,除非你真的需要,一般来说,直接回车即可是否配置 Shadowsocks ,如果不需要就直接回车,否则就输入 Y 回车Shadowsocks 端口,密码,加密方式这些东西自己看情况配置即可,一般全部直接回车。。OK,按回车继续最后安装完成后会提示安装信息,建议记录下。V2Ray 高级玩法快速管理 V2Rayv2ray info:查看 V2Ray 配置信息v2ray config:修改 V2Ray 配置v2ray link:生成 V2Ray 配置文件链接v2ray infolink:生成 V2Ray 配置信息链接v2ray qr:生成 V2Ray 配置二维码链接v2ray ss:修改 Shadowsocks 配置v2ray ssinfo:查看 Shadowsocks 配置信息v2ray ssqr:生成 Shadowsocks 配置二维码链接v2ray status:查看 V2Ray 运行状态v2ray start:启动 V2Rayv2ray stop:停止 V2Rayv2ray restart重启 V2Rayv2ray log:查看 V2Ray 运行日志v2ray update:更新 V2Rayv2ray update.sh:更新 V2Ray 管理脚本v2ray uninstall:卸载 V2RayTCP 阻断如果觉得机器出现了这种情况,那么可以尝试使用 UDP 协议相关的 mKCP。如果使用了一键脚本,直接输入 v2ray config 然后选择修改 V2Ray 传输协议,之后再选择 mKCP 相关的就行备注:使用 mKCP 或许还可以提高速度,但由于 UDP 的原因也许会被运营商 Qos,这是无解的。WebSocket + TLS实现 WebSocket + TLS 很简单,前提是要拥有一个能正常解析的域名 (并且知道怎么解析域名)服务器输入 v2ray config 回车,然后选择 修改 V2Ray 传输协议,再选择 WebSocket + TLS,即是输入 4,接着输入你的域名,总之按照提示进行操作就可以了HTTP/2实现 HTTP/2 (h2) 也很简单,和 WebSocket + TLS 一样,也就是只要一个域名就够了。服务器输入 v2ray config 回车,然后选择 修改 V2Ray 传输协议,再选择 HTTP/2,即是输入 16,然后参考上面的 WebSocket + TLS 的相关,或者按照提示即可。HTTP/2 相比 WS + TLS (WebSocket + TLS),在浏览网页时有一些优势,其他速度是差不多mKCPmKCP 其实就是 KCP 协议,一般能提速,但是不保证都能提速,还能避免 TCP 阻断,但是也可以会被运营商 Qos.使用方法:服务器输入 v2ray config 回车,然后选择 修改 V2Ray 传输协议,之后再选择 mKCP 相关的就行
2021年10月12日
1,146 阅读
0 评论
0 点赞
2021-07-05
Nginx+Lua实现Websocket实时网卡流量推送
首先我们先了解一下Linux系统获取网络流量的几种方法1.基于sysfs虚拟文件系统,这是由内核用来将设备或驱动相关的信息输出到用户空间的一种机制。网络接口的相关分析数据会通过“/sys/class/net/<ethX>/statistics”输出。加之Linux提供了LKM机制可以使我们在内核空间工作,在LKM机制中一个重要的组成部分就是proc伪文件系统,它为用户提供了动态操作Linux内核信息的接口,是除系统调用之外另一个重要的Linux内核空间与用户空间交换数据的途径。如:/sys/class/net/eth0/statistics/rx_packets: 收到的数据包数据/sys/class/net/eth0/statistics/tx_packets: 传输的数据包数量/sys/class/net/eth0/statistics/rx_bytes: 接收的字节数/sys/class/net/eth0/statistics/tx_bytes: 传输的字节数/sys/class/net/eth0/statistics/rx_dropped: 当收到包数据包下降的数据量/sys/class/net/eth0/statistics/tx_dropped: 传输包数据包下降的数据量2.sarsar命令包含在sysstat工具包中,提供系统的众多统计数据。其在不同的系统上命令有些差异,某些系统提供的sar支持基于网络接口的数据统计,也可以查看设备上每秒收发包的个数和流量。3./proc/net/dev本文使用的是方法1,即为通过定时读取/sys/class/net/eth0/statistics/xxx文件的内容,来进行计算,获取最终的网络带宽使用lua 的io库进行读文件操作file_rx = io. open ( "/sys/class/net/eth0/statistics/rx_bytes" , "r" ) file_tx = io. open ( "/sys/class/net/eth0/statistics/tx_bytes" , "r" ) local tx1 = file_tx : read ( "*l" ) local rx1 = file_rx : read ( "*l" )获得秒初的网络数据包数量进而通过ngx.sleep进行非阻塞的等待一秒后再次读取文件中的数据包数量ngx.sleep (1) file_rx :seek( "set" ) file_tx :seek( "set" ) local tx2 = file_tx : read ( "*l" ) local rx2 = file_rx : read ( "*l" )这样,获得了秒末的数据包数量将秒末的数据包数量减去秒初的数据包数量。即为秒内的网络流动数据包数量因为每个数据大小为8个字节,因此,得出的结果*8就是每秒字节数,进而可以通过多次除去1024得道千字节数,兆字节数等local tx = (tx2-tx1)*8 local rx = (rx2-rx1)*8 --and --tx = tx/1024/1024 --mbps --rx = rx/1024/1024 --mbps--核心代码实现 function read_network(types) file_rx = io. open ( "/sys/class/net/eth0/statistics/rx_bytes" , "r" ) file_tx = io. open ( "/sys/class/net/eth0/statistics/tx_bytes" , "r" ) local tx1 = file_tx : read ( "*l" ) local rx1 = file_rx : read ( "*l" ) ngx.sleep (1) file_rx :seek( "set" ) file_tx :seek( "set" ) local tx2 = file_tx : read ( "*l" ) local rx2 = file_rx : read ( "*l" ) local tx = (tx2-tx1)*8 local rx = (rx2-rx1)*8 mb = {time=ngx.now()} if (types == 1) then if (rx<10000) then mb["rx"]=rx mb["rx_mode"]="bps" elseif(rx<10000000) then rx = rx/1024 mb["rx"]=rx mb["rx_mode"]="Kbps" elseif(rx<10000000000) then rx = rx/1024/1024 mb["rx"]=rx mb["rx_mode"]="Mbps" elseif(rx<10000000000000) then rx = rx/1024/1024/1024 mb["rx"]=rx mb["rx_mode"]="Gbps" end if (tx<10000) then mb["tx"]=tx mb["tx_mode"]="bps" elseif(tx<10000000) then tx = tx/1024 mb["tx"]=tx mb["tx_mode"]="Kbps" elseif(tx<10000000000) then tx = tx/1024/1024 mb["tx"]=tx mb["tx_mode"]="Mbps" elseif(tx<10000000000000) then tx = tx/1024/1024/1024 mb["tx"]=tx mb["tx_mode"]="Gbps" end elseif(types == 2) then mb["tx"]=tx/1024/1024 mb["tx_mode"]="Mbps" mb["rx"]=rx/1024/1024 mb["rx_mode"]="Mbps" else mb["tx"]=tx mb["tx_mode"]="bps" mb["rx"]=rx mb["rx_mode"]="bps" end file_rx :close() file_tx :close() return mb end因为将要使用websocket进行实时的数据传输,我们需要安装支持resty.websocket的扩展库,openresty用户默认就有,非openresty用户可前往https://github.com/openresty/lua-resty-websocket安装库安装过程可参考https://www.cnblogs.com/scotoma/p/3330190.htmlwebsocket相关代码local server = require "resty.websocket.server" local wb, err = server:new{ timeout = 50000, -- in milliseconds max_payload_len = 6553500, } if not wb then ngx.log(ngx.ERR, "failed to new websocket: ", err) return ngx.exit(444) end bytes, err = wb:send_text(json.encode({Msg="Connect OK,Service will traceback the traffic data soon",code = "OK"})) if not bytes then ngx.log(ngx.ERR, "failed to send a text frame: ", err) end while (1) do bytes, err = wb:send_text(json.encode(read_network(types,pod))) if not bytes then ngx.log(ngx.ERR, "failed to send a text frame: ", err) end end全部完整代码json = require "cjson" ngx.update_time() local server = require "resty.websocket.server" local wb, err = server:new{ timeout = 50000, -- in milliseconds max_payload_len = 6553500, } if not wb then ngx.log(ngx.ERR, "failed to new websocket: ", err) return ngx.exit(444) end function read_network(types) file_rx = io. open ( "/sys/class/net/eth0/statistics/rx_bytes" , "r" ) file_tx = io. open ( "/sys/class/net/eth0/statistics/tx_bytes" , "r" ) local tx1 = file_tx : read ( "*l" ) local rx1 = file_rx : read ( "*l" ) ngx.sleep (1) file_rx :seek( "set" ) file_tx :seek( "set" ) local tx2 = file_tx : read ( "*l" ) local rx2 = file_rx : read ( "*l" ) local tx = (tx2-tx1)*8 local rx = (rx2-rx1)*8 mb = {time=ngx.now()} if (types == 1) then if (rx<10000) then mb["rx"]=rx mb["rx_mode"]="bps" elseif(rx<10000000) then rx = rx/1024 mb["rx"]=rx mb["rx_mode"]="Kbps" elseif(rx<10000000000) then rx = rx/1024/1024 mb["rx"]=rx mb["rx_mode"]="Mbps" elseif(rx<10000000000000) then rx = rx/1024/1024/1024 mb["rx"]=rx mb["rx_mode"]="Gbps" end if (tx<10000) then mb["tx"]=tx mb["tx_mode"]="bps" elseif(tx<10000000) then tx = tx/1024 mb["tx"]=tx mb["tx_mode"]="Kbps" elseif(tx<10000000000) then tx = tx/1024/1024 mb["tx"]=tx mb["tx_mode"]="Mbps" elseif(tx<10000000000000) then tx = tx/1024/1024/1024 mb["tx"]=tx mb["tx_mode"]="Gbps" end elseif(types == 2) then mb["tx"]=tx/1024/1024 mb["tx_mode"]="Mbps" mb["rx"]=rx/1024/1024 mb["rx_mode"]="Mbps" else mb["tx"]=tx mb["tx_mode"]="bps" mb["rx"]=rx mb["rx_mode"]="bps" end file_rx :close() file_tx :close() return mb end local types = tonumber(ngx.var.arg_types) or 0 local pod = ngx.var.arg_pod or "tx" bytes, err = wb:send_text(json.encode({Msg="Connect OK,Service will traceback the traffic data soon",code = "OK"})) if not bytes then ngx.log(ngx.ERR, "failed to send a text frame: ", err) end while (1) do bytes, err = wb:send_text(json.encode(read_network(types,pod))) if not bytes then ngx.log(ngx.ERR, "failed to send a text frame: ", err) end end详细项目地址https://gitee.com/daofengql/lua-websocket-real-time-network-traffic到此,lua部分已经编写完毕,接下来就要在nginx中配置配置文件来接入路由样例conflocation / { #路由名称具实际修改 #lua_code_cache off; default_type text/html; add_header 'Access-Control-Allow-Origin' *; content_by_lua_file /data/traffic.lua;#文件存放地址更具实际修改 } 配置完成后,如果不出意外,重载NGINX之后,可以使用在线websocket测试,测试服务推送出去,客户端收到的是json字符,可以再对其转化为字典对象等可以进一步将项目仓库内的html目录下的页面进行适当的修改和部署计数器核心功能代码<script language="JavaScript"> $(function () { var chart; var previous = null; var chart; // global var pointx = null; var ip = "180.188.16.147"; $(window).load(function () { initiateChart("L4dstat"); //parseFile(); }); var server = 'wss://ws.jcdpn.cn/?types=2'; var ws = new WebSocket(server); var temp_arr = [0.1]; var max_bps = 0.1; ws.onclose = function () { reconnect(service); }; ws.onmessage = function (evt) { data = JSON.parse(evt.data); temp_arr.push(data.rx); max_bps = Math.max.apply(null, temp_arr); temp_arr = [0.1]; var series = chart.series[0], shift = series.data.length > 20; chart.series[0].addPoint([Math.floor($.now()), max_bps], true, shift); max_bps = 0.1; }; function initiateChart(divid) { var options = { plotOptions: { series: { events: { legendItemClick: function (event) { event.preventDefault(); } } } }, chart: { zoomType: '', renderTo: divid, style: { fontFamily: "'Unica One', sans-serif" }, //plotBorderColor: '#606063' backgroundColor: '#e2e3e5', }, //title:{ // text: null // }, title: { text: '» '+ip+'核心流量计数器 «', }, xAxis: { type: 'datetime', dateTimeLabelFormats: { day: '%a' } }, yAxis: { minPadding: 0.2, maxPadding: 0.2, title: { text: 'Mb/秒', margin: 80 } }, credits: { enabled: false }, series: [{ type: 'area', //shadowSize: 0, name: 'Mbps/秒', color: '#164791', data: [] }] }; chart = new Highcharts.Chart(options); } }); </script>例如将默认的socket地址改成自己的流量计数器默认使用的单位为mbps,其他单位还需要自己修改和换算流量计数器使用highcharts.js来进行表格绘制效果
2021年07月05日
80 阅读
0 评论
0 点赞
2021-05-30
Python3操作Redis数据库(二)
7.psetex(name, time_ms, value) time_ms - 过期时间(数字毫秒 或 timedelta对象)import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.psetex("whoisdaofeng", 5000, "a dragon") time.sleep(5) print(r.get('whoisdaofeng')) # 5秒后,取值就从a dragon变成None8.mset(*args, **kwargs) 批量获取print(r.mget('daofengql', 'name'))10.getset(name, value)print(r.getset("daofengql", "strong dragon")) # 设置的新值是strong dragon 设置前的值是a dragon print(r.get('daofengql'))11.getrange(key, start, end) 获取子序列(根据字节获取,非字符)参数:name - Redis 的 namestart - 起始位置(字节)end - 结束位置(字节)r.set("name", "道峰潜鳞") print(r.getrange("name", 0, 2)) # 取索引号是0-2 前3位的字节 道 切片操作 一个汉字3个字节 1个字母一个字节 每个字节8bit12.setrange(name, offset, value) 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)参数:offset - 字符串的索引,字节(一个汉字三个字节)value - 要设置的值r.set("ename","da") r.setrange("ename", 1, "daofengql") print(r.get("ename"))13.strlen(name) 返回name对应值的字节长度(一个汉字3个字节)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set("dragon","daofengql") print(r.strlen("dragon")) # 9 'daofengql'的长度是9 14.incr(self, name, amount=1) 自增 name 对应的值,当 name 不存在时,则创建 name=amount,否则,则自增。参数:name - Redis的nameamount - 自增数(必须是整数)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set("data1", 1) print(r.get("data1")) for i in range(0,30): r.incr("data1", amount=1) print(r.get("data1")) print(r.get("data2")) for i in range(0,30): r.incr("data2", amount=1) print(r.get("data2")) 15.incrbyfloat(self, name, amount=1.0) 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。参数:name - Redis的nameamount - 自增数(浮点型)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set("data1", "1.0") print(r.get("data1")) for i in range(0,30): r.incrbyfloat("data1", amount=0.1) print(r.get("data1")) print(r.get("data2")) for i in range(0,30): r.incrbyfloat("data2", amount=0.1) print(r.get("data2")) 16.delete(keyname) 删除键import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set("data1", "1") print(r.get("data1")) r.delete("data1") print(r.get("data1")) 未完待续...
2021年05月30日
82 阅读
1 评论
0 点赞
2021-05-30
Python3操作Redis数据库(一)
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。首先安装一个Python-redis的包使用PIP pip install redis 或者使用 pip3 install redis测试是否安装成功:import redis那么,启动redis服务来测试一下(注:各环境下Redis服务各有不同,这里以Windows版为例)测试这里建立简单连接来测试>>> import redis >>> r = redis.StrictRedis(host='localhost', port=6379, db=0) >>> r.set('foo', 'bar') True >>> r.get('foo') 'bar'可以通过查看子类来了解所包含的参数选项这里Redis是StrictRedis的子类 def __init__(self, host='localhost', port=6379, db=0, password=None, socket_timeout=None, socket_connect_timeout=None, socket_keepalive=None, socket_keepalive_options=None, connection_pool=None, unix_socket_path=None, encoding='utf-8', encoding_errors='strict', charset=None, errors=None, decode_responses=False, retry_on_timeout=False, ssl=False, ssl_keyfile=None, ssl_certfile=None, ssl_cert_reqs=None, ssl_ca_certs=None):redis 提供两个类 Redis 和 StrictRedis, StrictRedis 用于实现大部分官方的命令,Redis 是 StrictRedis 的子类,用于向后兼用旧版本。redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。>>> import redis # 导入redis 模块 >>> r = redis.Redis(host='localhost', port=6379, decode_responses=True) >>> r.set('name', 'daofengql') # 设置 name 对应的值 True >>> print(r['name']) daofengql >>> print(r.get('name')) # 取出键 name 对应的值 daofengql >>> print(type(r.get('name'))) # 查看类型 <class 'str'> >>>连接池redis-py 使用 connection pool 来管理对一个 redis server 的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数 Redis,这样就可以实现多个 Redis 实例共享一个连接池。>>> import redis # 导入redis 模块 >>> pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) >>> r = redis.Redis(host='localhost', port=6379, decode_responses=True) >>> r.set('name', 'daofengql') # 设置 name 对应的值 True >>> print(r.get('name')) # 取出键 name 对应的值 daofengql >>>根据前面子类中对链接的定义,可以对照着传入其他参数,例如选择数据库的db数,安全链接的密码,超时等等例如:>>> import redis # 导入redis 模块 >>> pool = redis.ConnectionPool(host='localhost', port=6379,db=1,password="passwd", decode_responses=True)redis 基本命令 Stringset(name, value, ex=None, px=None, nx=False, xx=False)在 Redis 中设置值,默认,不存在则创建,存在则修改。参数:ex - 过期时间(秒)px - 过期时间(毫秒)nx - 如果设置为True,则只有name不存在时,当前set操作才执行xx - 如果设置为True,则只有name存在时,当前set操作才执行例:1.ex - 过期时间(秒) 这里过期时间是3秒,3秒后p,键food的值就变成Noneimport redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set('who', 'daofeng', ex=5) # 将键值对存入redis缓存设置5秒过期 print(r.get('who')) print(r.get('who'))2.px - 过期时间(豪秒) 这里过期时间是3豪秒,3毫秒后,键foo的值就变成Noneimport redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.set('daofengql', '1', px=3) print(r.get('daofengql'))3.nx - 如果设置为True,则只有name不存在时,当前set操作才执行 (新建)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) print(r.set('daofengql', 'a dragon', nx=True)) # True--不存在 # 如果键不存在,那么输出是True;如果键已经存在,输出是None4.xx - 如果设置为True,则只有name存在时,当前set操作才执行 (修改)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) print((r.set('name', 'a dragon', xx=True))) # True--已经存在 # 如果键已经存在,那么输出是True;如果键不存在,输出是None5.setnx(name, value)设置值,只有name不存在时,执行设置操作(添加)import redis pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) print(r.setnx('whois', 'a dragon')) # whois不存在,输出为True r.set('name', 'a dragon') print(r.setnx('name', 'a dragon')) # name存在,输出为False 6.setex(name, time, value) time - 过期时间(数字秒 或 timedelta对象)import redis import time pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) r.setex("whoisdaofeng", 5, "a dragon") time.sleep(5) print(r.get('whoisdaofeng')) # 5秒后,取值就从a dragon变成None 下接:Python3操作Redis数据库(二)
2021年05月30日
55 阅读
0 评论
0 点赞
2021-03-07
OpenResty-Lua之连接MySQL数据库
连接MySQL local mysql = require "resty.mysql" local db, err = mysql:new() if not db then ngx.say("failed to instantiate mysql: ", err) return end db:set_timeout(1000) --1 sec local ok, err, errno, sqlstate = db:connect{ host = "127.0.0.1", port = 3306, database = "test", user = "root", password = "vagrant", max_packet_size = 1024*1024 } if not ok then ngx.say("failed to connect: ",err, ":", errno, " ", sqlstate) return end res, err, errno, sqlstate = db:query("create table cats" .. "(id serial primary key, " .."name varchar(5))") if not res then ngx.say("bad result: ", err, ": ", errno, ":", sqlstate, ".") return end ngx.say("table cats created.") res, err, errno, sqlstate = db:query("insert into cats (name) " .. "values (\'Bob\'),(\'\'),(null)") if not res then ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".") return end样例2:local db, err = env:new() if not db then --错误处理 ngx.say(err) return end --设置超时 db:set_timeout(1000) --设置链接信息 local ok, err ,errcode ,sqlstate = db:connect{ database ="root",user = "root",password = "root",host = "127.0.0.1",port = 3306,charset = "utf8",max_packaget_size = 2048 * 2048 } --数据库命令主体 query = "select"; --数据库操作返回 local res, err ,errcode ,sqlstate = db:query(query) if not res then ngx.say(err) return end local ret = {} --数据库操作返回数据重构 for i,row in ipairs(res) do for key,raw in pairs(row) do ret[key] = raw end end --json编码进入 db:close()--关闭数据库连接需要安装Resty.mysql的库,非Openresty用户需要额外安装,resty.mysql库同时依赖resty.string库nginx配置文件部分:location /mysql_hello { content_by_lua_file XX.lua; }
2021年03月07日
101 阅读
0 评论
0 点赞
2021-02-25
Lua+Nginx 实现Wordpress外链跳转
Lua代码(保存为文件):p1 = [=[ <html><head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="referrer" content="always"> <title>道锋潜鳞 - 风控中心 - 跳转</title> <style> html,body{background:#F3F4F5;font-family: PingFang SC,Hiragino Sans GB,Arial,Microsoft YaHei,Verdana,Roboto,Noto,Helvetica Neue,sans-serif;padding:0;margin:0;} a{text-decoration:none;} .content{padding-top:220px;width:450px;margin:auto;word-break: break-all;} .content .logo-img img{display: block;width:175px;margin:auto;margin-bottom: 16px;} .content .loading-item{background:#fff;padding:24px;border-radius: 12px;border: 1px solid #E1E1E1;} .content .flex{display:flex;align-items:center;} .content .flex-end{display:flex;justify-content:flex-end} .content .tip1{background:#F0F9EA;} .content .tip2{background:#FDF5E6;} .content .tip3{background:#FEF0F0;} .content .loading-color1{color:#267DCC;} .content .loading-color2{color:#FC5531;} .content .loading-tip{padding:12px;margin-bottom:16px;border-radius:4px;} .content .loading-topic{font-size: 14px;color: #222226;line-height: 24px;margin-bottom:24px;} .content .loading-img{width:24px;height:24px;} .content .loading-btn{font-size: 14px;color: #FC5531;border: 1px solid #FC5531;display:inline-block;box-sizing: border-box;padding:6px 18px;border-radius: 18px;margin-left:8px;} .content .loading-btn2{font-size: 14px;color: #000000;border: 1px solid #000000;display:inline-block;box-sizing: border-box;padding:6px 18px;border-radius: 18px;margin-left:8px;} .content .loading-btn-github{width:121px;background:#FC5531;color:#fff;} .content .loading-text{font-size: 16px;font-weight: 600;color: #222226;line-height: 22px;margin-left:12px;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;} @media (max-width: 450px){ .content{padding-top:120px;width:94%;} } #csdn-toolbar{width: 0;height: 0;display: none} </style></head> <body class="vsc-initialized"> <div id="linkPage" class="link-page"> <div class="content"> <div class="logo-img"><img src="//objectstorage.global.loongapi.com/loongapiSources/picbed/olddata2/2021/02/logo-full.png" alt=""></div> <div class="loading-item loading-others"> <div class="flex loading-tip tip2"> <img class="loading-img" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADWUlEQVRoQ+2YvWsUQRiH33fmOMQiRQor7RQSweB9KAQEg1iYKFaZnJJ/wcTOMhLs7Ez8FwLebikasTGCoJDcHSoYQbHRyiKFhajczCu3SS73sbfzsXNJDnLV3s4y83vm3X12dhAG/IcDnh+OAHpVkITISvg2DYyQjwyVcXGt3o9q960CdZELAWC6ERoRn/CgentgAGimOCVJPmsNzJFfx2DjuW8I7xWg+xMZ9enXRwIaaQ2LgJ/Z2aFzvm8l7wBypjBPpB7FzTQiu8uDypLPKngFIDE+rODPFwIYjgUA2GJw7AyGb7d8QXgFkCK/TEB3ksIh4GMeVucOHQCV8qNKwQcCymgA6ozBGJarmz4gvFWgLvKrAHTNLBS+yITVSbNrk6/yAhCnTV04X1pNDdBLmzoAX1pNDZCkTS2EB62mAtBpUwvgQaupAEy0qYdIp1VnAFNtGgCk0qozgJ02tRjOWnUCoFJxUiqZuLJEgB+AbCWKTmqWAE4mYXDGp7C8sapD7Wy3BjDVJke8iUH1aZS/lL8hFUXHvX6uWrUGMNUmByxiWK1sAxTyUqnoOBHCQatWADbadAJw0KoVgJwpLBEpo5WkC0CjOohsmQeVeV21dtuNAWy16QwAaKVVYwBbbboCbM+s+WrVCMBEm50lTwcAYKpVLYCpNrsALDXa7XezTQAtgKk2Y14wVi+yuIfWZBMgEcBGm6bWsLkODbSaCGCjTZtgNtfqtNoTwFabMffwb0DYWQvBLAEdtwm+5/lkrfYEsNVmazgElIzxcSyvr0dLiVu5opL4joC4C0SSVmMBXLTZBoDwnge1863npMjVCKDtnA1ML612Abhqs70C8JPB6VMYhv+iCgiRVfD1OwGcsAndPim4yUaHxjr3VrsAZCk3RwpS718i4gpjdK8RQil8SESzruGbzwODeV6uLXdM1t7fg9amDjBOq20VOAza1EJ0rFabAGm1qRvYVzt2rFabAHWRa3zjetmv9BU2oZ/VTFibarRHACQuXJZQX9uHgb0NwZFdwaDyKgKQorBAoBa99b4PHSHCAx7UFnYqULikUL0mArYPY6ceInrTA05gWHmz9xCL4kWF6ioAZFOP0NcO8C8jerm746H9HuhrFg+dHwF4mMRUXQx8Bf4DeBHHQHvQneAAAAAASUVORK5CYII=" alt=""> <div class="loading-text">请注意您的账号和财产安全</div> </div> <div class="loading-topic"> <span>您即将离开,去往:</span> <a class="loading-color2"> ]=] p2 = [=[ </a> </p> <span>该链接不是我们的官方链接,风险不在我们的可控范围内</span> </div> <div class="flex-end"> <a class="loading-btn" href=" ]=] p3 = [=[ " target="_self" >继续</a> <a class="loading-btn2" href="#" onClick="javascript:history.back(-1);" target="_self">取消</a> </div> </div> </div> </div> </body> </html> ]=] resp = p1..ngx.var.arg_url..p2..ngx.var.arg_url..p3 ngx.say(resp)Nginx配置(部分):location ~ ^/goto/* { if ($request_method != GET) { return 403; } if ($arg_url = "") { return 403; } default_type text/html; content_by_lua_file /data/lua/link.lua; #前面lua代码的地址 }Wp:打开你的主题内的functions.php文件。在末尾添加如下php代码:function the_content_nofollow($content){ preg_match_all('/<a(.*?)href="(.*?)"(.*?)>/',$content,$matches); if($matches){ foreach($matches[2] as $val){ if(strpos($val,'://')!==false && strpos($val,home_url())===false && !preg_match('/\.(jpg|jepg|png|ico|bmp|gif|tiff)/i',$val)){ $content=str_replace("href=\"$val\"", "href=\"".home_url()."/goto?url=$val\" ",$content); } } } return $content; } add_filter('the_content','the_content_nofollow',999);实现效果:
2021年02月25日
77 阅读
0 评论
0 点赞
2021-02-14
Redis持久化RDB切换AOF
选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb),RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。redis默认持久化配置rdb,但是如果贸然切换配置到aof方式,重启会导致数据丢失如果数据不重要,都是缓存数据则没什么,如果是重要临时数据,不能丢失的情况,则需要特殊处理,保证数据不丢失根本原因rdb方式默认将数据持久化存储到dump.rdb文件下aof方式默认将数据写操作记录到appendonly.aof文件下如果同时开启2种方式,重启会默认加载aof方式redis默认只开启rdb综上,如果你是默认rdb方式,然后贸然切换到aof,重启后会读取aof文件,但是这个时候aof文件是空的,则会导致redis被清空解决方法原理:在redis控制台动态配置打开 aof方式,在 shutdown安全退出后,自动记录了当前所有记录到 aof文件,再修改redis文件配置打开 aof方式,启动redis时会自动加载之前安全退出保存的 aof数据进入redisredis-cliredis中动态修改配置并退出127.0.0.1:6379> save # 收到触发rdb存储数据 OK 127.0.0.1:6379> CONFIG SET appendonly yes # 动态配置 OK 127.0.0.1:6379> save OK 127.0.0.1:6379> shutdown save # 安全退出并存储数据 not connected> exit [root@localhost ~]# 修改redis配置,打开aofvim redis.confappendonly no #aof方式默认关闭启动redisservice redis start附录rdb配置save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。 save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。 save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。aof配置appendonly no #aof方式默认关闭 appendfilename "appendonly.aof" #文件名 appendfsync everysec #同步模式(可选no always everysec) no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes宝塔可以在动态修改配置保存之后直接编辑配置文件或者直接设置持久化然后启动服务即可那我想找到这个aof文件或者rdb文件怎么办?在服务启动后进入redis-cli127.0.0.1:6379> CONFIG GET dir #查看安装目录或者数据目录 1) "dir" 2) "/data/redis/redis_cache"进入目录后不出意外的话就能看到想要的aof和rdb文件了
2021年02月14日
86 阅读
0 评论
0 点赞
2021-02-09
php实现随机图片流输出
代码:<?php $img = 'ass/yinzhang'.rand(1, 4).'.png'; function reimage($src){ $mime = image_type_to_mime_type(exif_imagetype($src)); header('Content-Type:'.$mime); echo file_get_contents($src); } reimage($img); ?> 读取访问目标目录下的图片文件,名称为随机生成后拼接。每次访问页面的时候,可以返回不同的图片数据。PS:此为本站随机水印系统旧款代码,哈哈
2021年02月09日
57 阅读
0 评论
0 点赞
2021-02-09
Python Flask+Qrcode实现在线动态二维码生成
代码如下:from PIL import Image import qrcode from io import BytesIO from flask import Flask, send_file, jsonify, request, Response, json import sys import base64 import random import json #定义库区块 app = Flask(__name__) status_base64 = {} #返回状态码json源字典体 #二维码创建路由1 @app.route("/api/QRcode/create/", methods = ["GET", "POST"]) def code_share(): try: #尝试执行下方代码,判断请求主体的base64编码是否解码异常若异常则执行except区块的代码 if request.method=='GET': url64 = request.args.get("url") or "aHR0cHM6Ly9iLjRsMi5jbi8="#get获取URL参数 iconm = request.args.get("icon") or "logo"#GET获取logo参数 else: url64 = request.form.get("url") or "aHR0cHM6Ly9iLjRsMi5jbi8="#POST获取URL参数 iconm = request.form.get("icon") or "logo"#POST获取logo参数 url = base64.b64decode(url64).decode("utf-8") #转化url参数 except Exception as e: #若检测到处理异常,则转换返回模式变为json,返回相关错误的消息 status_base64["status"] = "error" status_base64["code"] = 1 status_base64["Msg"] = str(e) return Response(json.dumps(status_base64), mimetype='application/json') else: #若前方try执行正确无异常,则执行生成操作返回数据 return make_code(url,iconm) #生成器函数 def make_code(url,iconm): qr = qrcode.QRCode(version=8, error_correction=3, box_size=8, border=4) qr.add_data(url) qr.make(fit=True) img = qr.make_image()#初步生成 img = img.convert("RGBA") icon = Image.open("res/" + iconm +".png")#获取logo图片数据 img_w, img_h = img.size factor = 4 size_w = int(img_w / factor) size_h = int(img_h / factor) icon_w, icon_h = icon.size if icon_w > size_w: icon_w = size_w if icon_h > size_h: icon_h = size_h icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS) w = int((img_w - icon_w)/2) h = int((img_h - icon_h)/2) icon = icon.convert("RGBA") img.paste(icon, (w, h), icon) # img.show() byte_io = BytesIO() img.save(byte_io, 'PNG')#加载图片流 byte_io.seek(0) return send_file(byte_io, mimetype='image/png')#返回数据流中的图片 if __name__ == '__main__': app.run(host="0.0.0.0",port=8080,threaded=True)介绍QR Code码是由日本于1994年9月研制的一-种矩阵二维码符号,它具有一维条码及其它二 维条码所具有的信息容量大、可靠性高、可表示汉字及图象多种文字信息、保密防伪性强等优点。qrcode模块是Github_上的一-个开源项目,提供了生成二维码的接口。qrcode默认使用PIL库用于生成图像。由于生成qrcode图片需要依赖Python的图像库,所以需要先安装Python图像库PIL(Python Imaging Library)。QRCode二维码版本展示QR码符号共有40种规格,分别为版本1、版本....版本40版本1的规格为21模块x21模块,版本2为25模块x25模块,以此类推,每一版本符号比前一版本每边增加4个模块,直到版本40,规格为177模块X177模块。其中最高版本40可容纳多达1850个大写字母或2710个数字或1108个字节,或500多个汉字,比普通条码信息容量约高几十倍。由于其高密度编码,信息容量大,所以被广泛采用。QRCode方法qrcode.QRCode( version=1, error_ correction=qrcode.ERROR_ CORRECT_ _L, box_ size=10, border=4, image_ factory=None, mask_ pattern=None) 参数:* error_ correction:控制二维码纠错级别。 * ERROR_ CORRECT_ _L:大约7%或者更少的错误会被更正。 * ERROR_ CORRECT_ _M:默认值,大约15%或者更少的错误会被更正。 * ERROR_ CORRECT_ Q:大约25%或者更少的错误会被更正。 * ERROR_ CORRECT_ H:大约30%或者更少的错误会被更正。 * box_ size: 控制二维码中每个格子的像素数,默认为10。 * border:控制二维码四周留白包含的格子数,默认为4。 * image_ factory: 选择生成图片的形式,默认为PIL图像。 * mask_ pattern: 选择生成图片的的掩模。常用函数add_ _data(str,optimize=20):添加要转换的文字到data参数; 如果使用了optimize优化参数,数据将被拆分为多个块来进行优化,以找到一个长度至少为这个值的足够简洁的方式来生成二维码。设置为"0”以避免优化。make(fit=True):当fit参数为真或者没有给出version参数时,将会调用best_ fit方法来找到适合数据的最小尺寸。make_ image(ill color=None, back_ color=None,image_ factory=None):创建二维码的图像并返回,默认为PIL图像。使用如前代码,运行后访问url参数为url可传入文本,url等
2021年02月09日
107 阅读
0 评论
0 点赞
2021-01-30
Http压测工具wrk安装与分享
之前很长一段时间都在使用apachebench 俗称ab 但是用着用着,就觉得可玩性有点不足,尤其是在自定义这方面上。偶然间看到这款WRK压测工具wrk 的一个很好的特性就是能用很少的线程压出很大的并发量, 原因是它使用了一些操作系统特定的高性能 I/O 机制, 比如 select, epoll, kqueue 等。 其实它是复用了 redis 的 ae 异步事件驱动框架. 确切的说 ae 事件驱动框架并不是 redis 发明的, 它来至于 Tcl的解释器 jim, 这个小巧高效的框架, 因为被 redis 采用而更多的被大家所熟知.安装wrk支持大多数类UNIX系统,不支持windows。需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持。安装wrk非常简单,只要从github上下载wrk源码,在项目路径下执行make命令即可。wrk GitHub 源码:https://github.com/wg/wrkwrk只能运行于 Unix 类的系统上,也只能在这些系统上跑必备条件:1.软件包:gcc g++ make build-essential等(具体视系统而定)安装好了这些软件包后,进入源码目录git clone https://github.com/wg/wrk.git cd wrk make -j4(可选多线程)编译完成之后,目录下面会多一个 wrk 的文件。使用以下命令来测试一下:./wrk -c 1 -t 1 -d 1 http://www.baidu.com基本使用命令行敲下wrk,可以看到使用帮助Usage: wrk <options> <url> Options: -c, --connections <N> Connections to keep open -d, --duration <T> Duration of test -t, --threads <N> Number of threads to use -s, --script <S> Load Lua script file -H, --header <H> Add header to request --latency Print latency statistics --timeout <T> Socket/request timeout -v, --version Print version details Numeric arguments may include a SI unit (1k, 1M, 1G) Time arguments may include a time unit (2s, 2m, 2h)简单翻成中文:使用方法: wrk <选项> <被测HTTP服务的URL> Options: -c, --connections <N> 跟服务器建立并保持的TCP连接数量 -d, --duration <T> 压测时间 -t, --threads <N> 使用多少个线程进行压测 -s, --script <S> 指定Lua脚本路径 -H, --header <H> 为每一个HTTP请求添加HTTP头 --latency 在压测结束后,打印延迟统计信息 --timeout <T> 超时时间 -v, --version 打印正在使用的wrk的详细版本信息 <N>代表数字参数,支持国际单位 (1k, 1M, 1G) <T>代表时间参数,支持时间单位 (2s, 2m, 2h)测试1数据非常的明了测试2使用24线程 6000个链接,在海外G口机器上,使用随机脚本,达到了20WQPS的峰值数据(实际上约合10W)使用Lua脚本个性化wrk压测以上两节安装并简单使用了wrk,但这种简单的压测可能不能满足我们的需求。比如我们可能需要使用POST METHOD跟服务器交互;可能需要为每一次请求使用不同的参数,以更好的模拟服务的实际使用场景等。wrk支持用户使用--script指定Lua脚本,来定制压测过程,满足个性化需求。介绍wrk对Lua脚本的支持wrk支持在三个阶段对压测进行个性化,分别是启动阶段、运行阶段和结束阶段。每个测试线程,都拥有独立的Lua运行环境。启动阶段function setup(thread)在脚本文件中实现setup方法,wrk就会在测试线程已经初始化但还没有启动的时候调用该方法。wrk会为每一个测试线程调用一次setup方法,并传入代表测试线程的对象thread作为参数。setup方法中可操作该thread对象,获取信息、存储信息、甚至关闭该线程。thread.addr - get or set the thread's server address thread:get(name) - get the value of a global in the thread's env thread:set(name, value) - set the value of a global in the thread's env thread:stop() - stop the thread运行阶段function init(args) function delay() function request() function response(status, headers, body)init由测试线程调用,只会在进入运行阶段时,调用一次。支持从启动wrk的命令中,获取命令行参数;delay在每次发送request之前调用,如果需要delay,那么delay相应时间;request用来生成请求;每一次请求都会调用该方法,所以注意不要在该方法中做耗时的操作;reponse在每次收到一个响应时调用;为提升性能,如果没有定义该方法,那么wrk不会解析headers和body;结束阶段function done(summary, latency, requests)该方法在整个测试过程中只会调用一次,可从参数给定的对象中,获取压测结果,生成定制化的测试报告。自定义脚本中可访问的变量和方法变量:wrk wrk = { scheme = "http", host = "localhost", port = nil, method = "GET", path = "/", headers = {}, body = nil, thread = <userdata>, }一个table类型的变量wrk,是全局变量,修改该table,会影响所有请求。方法:wrk.fomat wrk.lookup wrk.connect function wrk.format(method, path, headers, body) wrk.format returns a HTTP request string containing the passed parameters merged with values from the wrk table. 根据参数和全局变量wrk,生成一个HTTP rquest string。 function wrk.lookup(host, service) wrk.lookup returns a table containing all known addresses for the host and service pair. This corresponds to the POSIX getaddrinfo() function. 给定host和service(port/well known service name),返回所有可用的服务器地址信息。 function wrk.connect(addr) wrk.connect returns true if the address can be connected to, otherwise it returns false. The address must be one returned from wrk.lookup(). 测试与给定的服务器地址信息是否可以成功创建连接示例使用POST METHODwrk.method = "POST" wrk.body = "foo=bar&baz=quux" wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"通过修改全局变量wrk,使得所有请求都使用POST方法,并指定了body和Content-Type头。为每次request更换一个参数request = function() uid = math.random(1, 10000000) path = "/test?uid=" .. uid return wrk.format(nil, path) end通过在request方法中随机生成1~10000000之间的uid,使得请求中的uid参数随机。每次请求之前延迟10msfunction delay() return 10 end每个线程要先进行认证,认证之后获取token以进行压测token = nil path = "/authenticate" request = function() return wrk.format("GET", path) end response = function(status, headers, body) if not token and status == 200 then token = headers["X-Token"] path = "/resource" wrk.headers["X-Token"] = token end end在没有token的情况下,先访问/authenticate认证。认证成功后,读取token并替换path为/resource。压测支持HTTP pipeline的服务init = function(args) local r = {} r[1] = wrk.format(nil, "/?foo") r[2] = wrk.format(nil, "/?bar") r[3] = wrk.format(nil, "/?baz") req = table.concat(r) end request = function() return req end通过在init方法中将三个HTTP request请求拼接在一起,实现每次发送三个请求,以使用HTTP pipeline附赠可用作变参破盾的脚本:wrk.method = "GET" --请求模式 radua = 1 -- 是否启用随机ua数据 1为开,其他均为关 radque = 1 -- 是否启用随机查询数据 1为开,其他均为关 uri = "/?p="--随机查询数据uri关键 仅仅在radque=1的时候生效 quemax = 100000 --最大随机查询生成大小 仅仅在radque=1的时候生效 --随机ua列表开始 ua = { "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60", "Opera/8.0 (Windows NT 5.1; U; en)", "Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0", "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0)", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.3.4000 Chrome/30.0.1599.101 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", "Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10", "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.337 Mobile Safari/534.1+", "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124", "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Titan)", "UCWEB7.0.2.37/28/999", "NOKIA5700/ UCWEB7.0.2.37/28/999", "Openwave/ UCWEB7.0.2.37/28/999", "Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1", "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "Sogou inst spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "Sogou News Spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "Sogou Pic Spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "Sogou Video Spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)", "Mozilla/5.0 (compatible; Bytespider; https://zhanzhang.toutiao.com/) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.0.0 Safari/537.36", "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; Bytespider; https://zhanzhang.toutiao.com/)", "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Version/7.0 Mobile Safari/537.36 (compatible; Bytespider; https://zhanzhang.toutiao.com/)", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0); 360Spider(compatible; HaosouSpider; http://www.haosou.com/help/help_3_2.html", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko)Version/4.0 Mobile Safari/534.30; 360Spider", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30; HaosouSpider", "Mozilla/5.0 (Linux; U; Android 4.3; zh-CN; SCH-N719 Build/JSS15J) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 YisouSpider/1.0.0 Mobile Safari/533.1", "Mozilla/5.0 (Linux;u;Android 4.2.2;zh-cn;) AppleWebKit/534.46 (KHTML,likeGecko) Version/5.1 Mobile Safari/10600.6.3 (compatible; Baiduspider/2.0;+http://www.baidu.com/search/spider.html)", "Mozilla/5.0 (compatible; Baiduspider/2.0;+http://www.baidu.com/search/spider.html)", "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 likeMac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143Safari/601.1 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)", "Mozilla/5.0(compatible;Baiduspiderrender/2.0;+http://www.baidu.com/search/spider.html)", "Baiduspider-image+(+http://www.baidu.com/search/spider.htm)" } --随机UA列表结束 request = function() if (radua == 1) then math.randomseed(tostring(os.time()):reverse():sub(1, 7)) wrk.headers["User-Agent"] = ua[math.random(1,74)] else wrk.headers["User-Agent"] = "Powered by WRK" end --随机ua传递结束 if (radque==1)then uid = math.random(1, quemax) path = uri .. uid end --随机查询结束 --返回数据开始 return wrk.format(null,path,wrk.headers,null) end --随机请求结束
2021年01月30日
125 阅读
1 评论
0 点赞
2021-01-09
宝塔nginx搭建rtmp推流服务器
环境Linux centos 7.6 + Nginx1.安装Nginx这一步就不用多说了吧我是宝塔用户,这边进入到/www/server/nginx/src目录里面使用nginx -V查看当前的编译选项。2.安装Nginx的rtmp拓展nginx的rtmp拓展包github地址:https://github.com/arut/nginx-rtmp-module,可以使用git clone下拉或者直接下载我这边直接下载解压放到:/root下。Nginx安装rtmp拓展:3.编译在刚刚-V操作所输出的 ./configure arguents:之后的内容复制然后在后头添加:--add-module=/opt/module/nginx-rtmp-module在前头添加./configure如:(我这里有编译云锁的安全模块,可以删除)./configure --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module --add-module=/root/nginx-plugin-master --add-module=/root/nginx-rtmp-module运行后没有错误的话执行 make -j8 (我这里是8个线程编译,可以根据具体机器的配置选配)make完成后将系统中原有的nginx用重新编译生成的nginx文件替换,替换后重启nginx使新编译nginx生效rm -rf /www/server/nginx/sbin/nginx cp objs/nginx /www/server/nginx/sbin/ service nginx restart4.配置Nginx的rtmp服务站点# 在文件底部添加下面内容: rtmp { server { listen 1935; #监听的端口 chunk_size 4000; application tv_file { live on; #开启实时 hls on; #开启hls hls_path /www/hls; #rtmp推流请求路径,文件存放路径 hls_fragment 5s; #每个TS文件包含5秒的视频内容 } } }另外切记,此段配置文件需要和http配置块同级,即不能将此段内容放在http{}内,否则无法启动且报错重启Nginx:nginx -s reload开放端口(没防火墙忽略此部)iptables -I INPUT -p tcp --dport 1938 -j ACCEPT附属步骤1:使用http-hls流(m3u8)(不需要此功能跳过这步)首先新建一个站点,在配置文件中添加类似这样的代码:add_header 'Access-Control-Allow-Origin' *; add_header 'Access-Control-Allow-Methods' GET; location /live { #error_page 404 =200 /nosign.m3u8; #可以取消注释上面的代码,稍作修改即可配置默认视频流 types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /www/hls/; }这段配置文件将前一步生成的m3u8和ts文件以http的形式推送。可以再添加CDN进行分发,但注意缓存时间需要匹配,否则会出现视频流异常。附属步骤2:读取http-hls流(m3u8)(不需要此功能跳过这步)完成上面附属一之后,可以使用如下html代码读取播放此m3u8视频源<script src="https://www.silverdragon.cn/wp-content/themes/hestia/assets/js/hls.min.js"></script> <video id="video" class="wrap" controls="" poster="封面图片"></video> <script> var url = "你的hls地址"; if(Hls.isSupported()) { var video = document.getElementById('video'); var hls = new Hls(); hls.loadSource(url); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED,function() { video.play(); }); } </script>5、推拉流测试推流。下载OBS Studio,官网下载太慢了,其他下载地址:https://pc.qq.com/detail/4/detail_23604.html安装完成,打开软件,在控件版块点击设置,左边的导航选择流,然后流类型选择自定义流媒体服务器,url输入rtmp://你的IP:1935/tv_file(就是刚刚配置的那个),流名称随便设置一个在场景里头随便添加个视频或者什么七七八八的设置完成点击推流。在服务器就看到m3u8文件的生成,推流成功。(然后挂到后台)这边强烈建议调整为动态码率或者其他什么的,毕竟自己的服务器带宽小,一不小心就跑满了6、拉流。测试拉流下载VLC,官方也是慢的要死,可以普通下载:https://pc.qq.com/detail/9/detail_569.html安装后打开url输入rtmp://你的IP:1935/tv_file/流名称(秘钥)或者使用刚刚配置的hls流,输入http://你的域名或IP/live/流名称.m3u8拉取正常根据本教程可以做出类似本站https://www.silverdragon.cn/?page_id=2339的功能。
2021年01月09日
156 阅读
1 评论
0 点赞
2021-01-03
Python获取NGINX连接数(ngx_stub_status)
最近在写网站的自动化运营平台,其中有一个CC攻击报警的系统,需要获取到网络服务器实时的连接数来判断是否遭受到攻击。因为服务器资源还是比较充裕,所以只需要获取当前的并发连接数即可。但有一个问题,ngx_stub_status插件是以http页面的形式输出的。而且内容还是非json格式。于是就用到urllib模块,对监控地址进行请求import urllib.parse import urllib.request def data_re(): url = "https://youdomain.com/your-url" headers = { # 存储任意的请求头信息 'User-Agent': 'Automated_blog_server_monitoring_platform version1.0.0', 'Referer':url } request = urllib.request.Request(url=url, headers=headers) response = urllib.request.urlopen(request) the_page = response.read().decode("unicode_escape").splitlines() #从http读取目标页面的数据分行存入List变量中 connect = int(str(the_page[0]).split(':')[1].strip()) #处理链接数为int类型的变量 print(connect)可以同理获取到队列等待数等。代码原理:首先请求页面获取页面内容,然后对页面内容进行拆行解析。每一行为一个元素。使用split()对字符串进行二次拆解分割。最终去除多余的空格,解析出ngx_stub_status的Active connections同理可以略微改动代码获取到总处理数,队列等待数等数据。
2021年01月03日
135 阅读
0 评论
0 点赞
1
...
27
28
29
...
31