NGINX安装配置
1.检查并且安装依赖组件
检查安装nginx的依赖性,nginx的模块需要第三方库的支持,检查是否安装下列库:zlib、zlib-devel、openssl、openssl-devel、prce、prce-devel如果没有,则全部装上
# yum install zlib zlib-devel openssl openssl-devel prce prce-devel
2.安装pcre
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.10.tar.gz
# tar -xzvf pcre-8.10.tar.gz -C ../software/
# cd ../software/pcre-8.10/
# ./configure
# make && make install
3.安装google-perftools
# wget http://mirror.yongbok.net/nongnu/libunwind/libunwind-0.99-alpha.tar.gz
# wget http://mirror.yongbok.net/nongnu/libunwind/libunwind-0.99-alpha.tar.gz
# tar -xzvf libunwind-0.99-alpha.tar.gz -C ../software/
# tar -xzvf google-perftools-0.98.tar.gz -C ../software/
# cd ../software/libunwind-0.99-alpha/
# ./configure
# make
# make install
# cd ../google-perftools-0.98/
# ./configure
# make && make install
4.编译安装NGINX
先建nginx的启动用户
# useradd –s /sbin/nologin nginx
# wget http://nginx.org/download/nginx-1.0.4.tar.gz
# tar -xzvf nginx-1.0.4.tar.gz -C ../software/
# cd ../software/nginx-1.0.4/
# ./configure
--with-cc-opt='-O3' \ # 注意整个不是零,是大写英文字母O
--with-google_perftools_module \ # 可选组件
--prefix=/usr/local/nginx \ # nginx安装目录
--with-openssl=/usr/lib
--with-http_stub_status_module
--with-http_image_filter_module
--user=nginx
--group=nginx
# make && make install
修改一下配置:
# grep nginx /usr/local/nginx/conf/nginx.conf
user nginx nginx;
要点:禁止DEBUG模式
# vi auto/cc/gcc
# debug //注释下面
CFLAGS="$CFLAGS -g"
5.nginx的信号控制(有关nginx的启动与关闭)
TERM,INT 快速关闭
QUIT 从容关闭
HUP 平滑重启,重新加载配置文件
USR1 重新打开日志文件,在切割日志时用途较大;
USR2 平滑升级可执行程序
WINCH 从容关闭工作进程
我们可以直接通过以下命令来完成平滑重启,省下寻找nginx主进程号的步骤;
kill -"信号类型”‘/usr/local/nginx/logs/nginx.pid'或者nginx的主进程号
(1)、从容停止nginx
kill -QUIT 6019 #nginx主进程号
kill -QUIT cat /usr/local/nginx/logs/nginx.pid
(2)、快速停止nginx
kill -TERM /INT nginx主进程号
kill -TERM /INT cat /usr/local/nginx/logs/nginx.pid
(3)、强制停止所有的nginx进程
pkill -9 nginx
(4)、平滑重启nginx
修改了nginx的配置文件要重启nginx;重启之前要检查配置文件是否正确:
# /usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful
# kill -HUP 
cat /usr/local/nginx/logs/nginx.pid`
nginx的平滑重启
kll HUP Nginx主进程号
或者
kll HUP nginx.pid文件按存放路径•

NGINX基本配置
Nginx.conf配置文件:
//以下为配置内容
user nginx; # 指定运行nginx的用户和组
worker_processes 2; # 工作进程数,基本为CPU的核心数或者两倍
# 指定全局错误日志的路径,错误日志可选项 有[debug|info|notice|warn|error|crit]
error_log logs/error.log info;
pid logs/nginx.pid; # 指定pid文件位置
events {
worker_connections 1024; # 最大连接数
}
http {
include mime.types; # 设定mime类型
default_type application/octet-stream;
//定义日志格式
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main; # 访问日志目录以及格式
sendfile on; # sendfile有效提高web文件传输速度
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
#站点配置
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
//定义主目录,类似apache的DocumentRoot
location / {
root /nginx_www; # 网站根目录
index index.html index.htm; # 默认首页
}
error_page 404 /404.html; # 404错误页面
error_page 500 502 503 504 /50x.html; # 将500错误转到50x.html上
location = /50x.html { # 如果访问的页面等于50x.html,则从html目录下找
root /nginx_www;
}
}
}
首先有个全局的配置
然后配置一个httpd段
httpd配置段里面包含多个server段,也就是常说的虚拟主机
server段里面可以配置各个站点特有的配置

NGINX每个进程配置一个CPU
nginx进程设置方法, worker_processes 1;
查看CPU个数:
cat /proc/cpuinfo | grep processor
配置1:4 CPU (4 Core) + 4 worker_processes (每个worker_processes 使用1个CPU)
orker_processes 4;
orker_cpu_affinity 0001 0010 0100 1000;
配置2:8 CPU (8 Core) + 8 worker_processes (每个worker_processes 使用1个CPU)
orker_processes 8;
orker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
配置3:16 CPU (16 Core) + 16 worker_processes (每个worker_processes 使用1个CPU)
orker_cpu_affinity 0000000000000001 0000000000000010 0000000000000100 0000000000001000 0000000000010000 0000000000100000 0000000001000000 0000000010000000 0000000100000000 0000001000000000 0000010000000000 0000100000000000 0001000000000000 0010000000000000 0100000000000000 1000000000000000;

基于域名的虚拟主机配置
1.两个站点分别为:Web1.ttlsa.com、Web2.ttlsa.com
搭建web1主目录、搭建web2主目录
# mkdir /nginx_www/web1.ttlsa.com
# echo “web1.ttlsa.com” > /nginx_www/index.html
# mkdir /nginx_www//nginx_www/web2.ttlsa.com
# echo “web2.ttlsa.com” > /nginx_www/ web2.ttlsa.com/index.html
在http配置段里增加如下配置:
server {
listen 80;
server_name web1.ttlsa.com;
location / {
root /nginx_www/web1.ttlsa.com; # 网站根目录
index index.html index.htm; # 默认首页
}
error_page 404 /404.html; # 404错误页面
error_page 500 502 503 504 /50x.html;
}
server {
listen 80;
server_name web2.ttlsa.com;
location / {
root /nginx_www/web2.ttlsa.com; # 网站根目录
index index.html index.htm; # 默认首页
}
error_page 404 /404.html; # 404错误页面
error_page 500 502 503 504 /50x.html;
}
2.开始做个本地测试,先要修改windows下的hosts文件,加入如下配置
C:\Windows\System32\drivers\etc\hosts
192.168.1.203 web1.ttlsa.com
192.168.1.203 web2.ttlsa.com

NGINX配置文件过期时间expires
# 参数off禁止修改应答头中的"Expires"和"Cache-Control"。
# 注意:expires仅仅适用于200, 204, 301, 302,和304应答
1.根据文件类型配置(大部分情况下是这么配置的)
对图片,flash文件在浏览器本地缓存30天
expires on # 启用设置expire过期时间
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
对js,css文件在浏览器本地缓存1小时
location ~ .*\.(js|css)$
{
expires 1h;
}
2.根据目录来设置
location ~ ^/(image|js|static|flash)/{
root /nginx_www/down; # 匹配这些url主目录都在down下,并且过期时间为30
expires 30d;
}

NGINX配置禁止访问某类文件
1.使用break
location ~ .*\.(exe|doc|rar)$
{
if (-f $request_filename) # 注意if和(之间有个空格
{
root /nginx/x; #当名字匹配时,把网站根目录替换成其他目录,使得用户无法下载
break; # 当名字匹配时,直接跳出不处理
}
}
范例一:假如说我有一个txt文件在web1.ttlsa.com上,我不让别人访问,那么怎么做呢?
现在目录下建一个txt文件
# vi /nginx_www/web1.ttlsa.com/a.txt
最后修改一下nginx.conf配置,Server段配置段如下:
server{
listen 80;
server_name web1.ttlsa.com;
location / {
root /nginx_www/web1.ttlsa.com;
index index.html index.htm;
}
error_page 404 /404.html;
location ~ \.txt$ {
if (-f $request_filename)
{
#root /nginx/xxx;
break;
}
}
}
接着我们来测试访问,可以看到提示404 Not Found
2.使用deny
location ~ .*\.(exe|doc|rar)$
{
root /nginx/x; #当名字匹配时,把网站根目录替换成其他目录,使得用户无法下载
deny all;
}

禁止访问某个目录
location ~ ^/(admin)/ {
deny all; # 所有访问/admin目录的URL都被拒绝掉
}

限制某些ip访问
location / {
deny 192.168.1.1;
deny 192.168.2.0/24;
allow all; # 上面呢两个被拒绝,允许其他所有的ip
}

nginx下载连接数限制、速度限制
1.limit_zone
语法:limit_zone zone_name $variable memory_max_size
默认值:no
使用字段:http
指令描述会话状态存储区域。
会话的数目按照指定的变量来决定,它依赖于使用的变量大小和memory_max_size的值。
如下例:
limit_zone one $binary_remote_addr 10m;
客户端的地址将用于会话,注意$binary_remote_addr变量将替换$remote_addr而被使用。
$remote_addr 变量的值的长度可以是7到15字节,因此大小指定为32或64字节。
$binary_remote_addr 变量的值的长度总是4字节,大小总是32字节。
当会话状态储存区域为1M时理论上可以处理32000个会话,每个会话大小为32字节。
2.limit_conn
语法:limit_conn zone_name max_clients_per_ip
默认值:no
使用字段:http, server, location
指令指定一个会话的最大同时连接数,超过这个数字的请求将被返回"Service unavailable" (503)代码。
如下例:
limit_zone one $binary_remote_addr 10m; # 使用10MB来存储会话,可存32w个会话
Server{
Listen 80;
Server_name download.ttlsa.com;
Index index.html index.html index.php;
#Zone limit
Location / {
limit_conn one 1; # 值允许一个连接
limit_rate 20k; # 一个连接最大20k速度
}
}
接下来我们测试一下效果,我在web1.ttlsa.com根目录下传了一个飞信的安装包,20多MB,看看速度是多少吧,接近20KB/秒.
这次把速度开到50KB,连接数还是1,配置段如下
limit_conn one 1;
limit_rate 50k;
连接数改成10,速率到50KB,速度应该达到250KB/秒左右了吧
limit_conn one 10;
limit_rate 50k;

Nginx列出目录下的列表-目录索引
整个站点
location / {
root /nginx/web1.ttlsa.com
autoindex on;
}
也可以单个目录
location / {
root /nginx/web1.ttlsa.com/list; # 要索引的目录
autoindex on; # 打开索引
}
接下来看看整个列子,把web1.ttlsa.com的list索引目录列出,配置如下
server{
listen 80;
server_name web1.ttlsa.com;
location / {
root /nginx_www/web1.ttlsa.com;
index index.html index.htm;
}
error_page 404 /404.html;
location /list
{
root /nginx_www/web1.ttlsa.com;
autoindex on;
默认关闭状态
autoindex_exact_size off;
默认为on,显示出文件的确切大小,单位是bytes。
改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_localtime on;
默认为off,显示的文件时间为GMT时间。
改为on后,显示的文件时间为文件的服务器时间
}
}

NGINX日志处理
设置一个计划任务,每天12点把access.log剪切到一个目录下,并且从命名为响应的名字

NGINX忽略部分日志
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
access_log off; # 列出的这些图片格式不记录日志
}

NGINX反向代理配置
nginx.conf配置文件:
user nobody nobody;
worker_processes 4;
error_log logs/error.log crit;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 65535;
}
http {
server_tokens off;
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
upstream mysrv {
server 192.168.1.1:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.2:80 weight=1 max_fails=2 fail_timeout=30s;
}
upstream bench {
server 192.168.1.3:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.4:80 weight=1 max_fails=2 fail_timeout=30s;
}
upstream bbs {
server 192.168.1.5:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.6:80 weight=1 max_fails=2 fail_timeout=30s;
}
include vhost/*.conf;
}
aaa_example_com.conf配置文件:
server
{
listen 80;
server_name aaa.example.com;
index index.php index.html index.htm index.shtml;
log_format proxy '$remote_addr| $upstream_addr| $connection| $upstream_status| $time_local| $request|'
'$status| $body_bytes_sent| $bytes_sent| $http_referer|'
' $http_user_agent| $upstream_response_time| $msec| $request_time';
access_log logs/aaa_access.log proxy;
location /
{
proxy_pass http://mysrv; # 当访问aaa.example.com,默认解析转发到后端的mysrv
include proxy.conf;
}
location /bench/
{
proxy_pass http://bench; #当访问/bench/转发到upstream配置的bench下
I nclude proxy.conf;
}
}
bbs_example_com.conf配置文件:
server
{
listen 80;
server_name bbs.example.com *.bbs.example.com;
log_format proxy '$remote_addr| $upstream_addr| $connection| $upstream_status| $time_local| $request|'
' $status| $body_bytes_sent| $bytes_sent| $http_referer|'
' $http_user_agent| $upstream_response_time| $msec| $request_time';
access_log logs/bbs_access.log proxy;
location /
{
proxy_pass http://bbs;
include proxy.conf;
}
}
proxy.conf配置文件:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m; # 允许客户端请求的最大单个文件字节数
client_body_buffer_size 256k; # 缓冲区代理缓冲客户端请求的最大字节数
proxy_connect_timeout 30; # 连接后端服务器超时时间
proxy_send_timeout 30; # 后端服务器发送数据超时时间,连接以及建立
proxy_read_timeout 60; # 后端服务器响应请求超时时间,从开始发送到接受完毕
proxy_buffer_size 4k; # 代理请求缓存区大小
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k; #系统繁忙时可申请的proxy_buffers大小
proxy_temp_file_write_size 64k; #proxy缓存临时文件的大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
# 故障转移
proxy_max_temp_file_size 128m;
proxy_set_header指令用于在向反向代理的后端web服务器发起请求时添加指定Header头信息,当后端web服务器上有多个基于域名的虚拟主机时,要通过添加Header头信息Host,来指定请求的域名,这样后端web服务器才能识别该反向代理访问请求由哪个虚拟主机来处理。

Nginx缓存服务器配置
# wget http://labs.frickle.com/files/ngx_cache_purge-1.3.tar.gz //清缓存模块
# tar zxvpf ngx_cache_purge-1.3.tar.gz -C ../software/
# cd /usr/local/src/software/nginx-1.0.2
# ./configure --user=nobody --group=nobody --prefix=/usr/local/nginx-1.0.2 --with-http_stub_status_module --with-http_ssl_module --add-module=../ngx_cache_purge-1.3
# mkdir -p /www/nginx/proxy_temp_path
# mkdir -p /www/nginx/proxy_cache_path
nginx.conf配置文件:
user nobody nobody;
worker_processes 4;
error_log logs/error.log crit;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 65535;
}
http {
server_tokens off;
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
upstream mysrv {
server 192.168.1.1:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.1.2:80 weight=1 max_fails=2 fail_timeout=30s;
}
include vhost/*.conf;
}
aaa_example_com.conf配置文件:
server {
listen 80;
server_name aaa.example.com;
index index.php index.html index.htm index.shtml;
log_format proxy '$remote_addr| $upstream_addr| $connection| $upstream_status| $time_local| $request|'
' $status| $body_bytes_sent| $bytes_sent| $http_referer|'
' $http_user_agent| $upstream_response_time| $msec| $request_time';
access_log logs/aaa_access.log proxy;
location /
{
proxy_pass http://mysrv;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
proxy_pass http://mysrv;
include proxy.conf;
}
location ~ /purge(/.*)
{
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}
}
proxy.conf配置文件:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m; //允许客户端请求的最大单个文件字节数
client_body_buffer_size 256k; //缓冲区代理缓冲客户端请求的最大字节数
proxy_connect_timeout 30; //连接后端服务器超时时间
proxy_send_timeout 30; //后端服务器发送数据超时时间
proxy_read_timeout 60; //后端服务器响应请求超时时间
proxy_buffer_size 4k; //代理请求缓存区大小
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k; //系统繁忙时可申请的proxy_buffers大小
proxy_temp_file_write_size 64k; //proxy缓存临时文件的大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
//故障转移
proxy_max_temp_file_size 128m;
proxy_temp_path /www/nginx/proxy_temp_path;
proxy_cache_path /www/nginx/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=1g; //设置web缓存区名称为cache_one,内存缓存空间为200m,自动清除超过1天没有被访问的缓存数据,硬盘缓存空间为1g
proxy_cache cache_one; //使用web缓存区cache_one
proxy_cache_valid 200 304 12h;
proxy_cache_valid 301 302 1m;
proxy_cache_valid any 1m;
proxy_cache_key $host$uri$is_args$args; //设置web缓存的key值,nginx根据key值md5哈希存储缓存

Linux运维文档之nginx的更多相关文章

  1. Grafana-监控-报警-运维文档

    Grafana运维文档 2019/09/23 Chenxin Wuweiwei 参考资料 https://grafana.com/grafana https://blog.52itstyle.vip/ ...

  2. 大厂0距离:网易 Linux 运维工程师面试真题,内含答案

    作为 Linux 运维工程师,进入大公司是开启职业新起点的关键,今天马哥 linux 运维及云计算智囊团的小伙伴特别分享了其在网易面试 Linux 运维及云计算工程师的题目和经历,希望对广大 Linu ...

  3. Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!

    Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Disc ...

  4. 运维 03 Linux之文档与目录结构

    Linux之文档与目录结构   Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到 ...

  5. 做linux运维工程师,必须要掌握以下几个工具

    linux系统如果是学习可以选用redhat或centos,特别是centos在企业中用得最多,当然还会有其它版本的,但学习者还是以这2个版本学习就行,因为这两个版本都是兄弟,没区别的,有空可以再研究 ...

  6. Linux运维入门到高级全套常用要点

    Linux运维入门到高级全套常用要点 目 录 1. Linux 入门篇................................................................. ...

  7. 要做linux运维工程师的朋友,必须要掌握以下几个工具才行 ...

    要做linux运维工程师的朋友,必须要掌握以下几个工具才行 ...  [复制链接]   发表于 2013-12-13 15:59 | 来自  51CTO网页 [只看他] 楼主           本人 ...

  8. Linux运维之道(大量经典案例、问题分析,运维案头书,红帽推荐)

    Linux运维之道(大量经典案例.问题分析,运维案头书,红帽推荐) 丁明一 编   ISBN 978-7-121-21877-4 2014年1月出版 定价:69.00元 448页 16开 编辑推荐 1 ...

  9. Linux运维工程师入门的10大实用工具

    说到工具,在行外可以说是技能,在行内我们一般称为工具,就是运维必须要掌握的工具. 我就大概列出这几方面,这样入门就基本没问题了. 工具如下: 1.Linux系统基础 这个不用说了,是基础中的基础,连这 ...

随机推荐

  1. 大白话讲解BP算法(转载)

    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...

  2. 瓣呀,一个基于豆瓣api仿网易云音乐的开源项目

    整体采用material design 风格,本人是网易云音乐的粉丝,所以界面模仿了网页云音乐,另外,项目中尽量使用了5.0之后的新控件. 项目整体采用mvp+rxjava+retrofit 框架,使 ...

  3. ES6 extends继承及super使用读书笔记

    extends 继承 extends 实现子类的继承 super() 表示父类的构造函数, 子类必须在 constructor中调用父类的方法,负责会报错. 子类的 this 是父类构造出来的, 再在 ...

  4. 洛谷P4316 绿豆蛙的归宿(期望)

    题意翻译 「Poetize3」 题目背景 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 题目描述 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出 ...

  5. mysql5.6 配置 文件

    mysql 3306 主库配置文件 [client] port = 3306 default-character-set=utf8mb4 socket = /ssd/mysql/3306/tmp/my ...

  6. 网页更换主题以及绘制图形js代码实现

    HTML代码实现: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. ASPX页面请求响应过程

  8. [记读书笔]python3.5实现socket通讯(UDP)

    UDP连接: 无连接,从一个端向另一端发送独立的数据分组 使用UDP连接的客户-服务器程序: UDPServer.py import socket serverPort = 50009 serverS ...

  9. 对于STM32别名区的理解 (转载)

    1. 什么是位段.位带别名区? 2. 它有什么好处? 答1: 是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,       MCS51可以简单的将P1口的第2位 ...

  10. java 值传递 和 引用传递

    参考:(http://www.cnblogs.com/woshimrf/p/5263018.html) 参考:(http://www.cnblogs.com/binyue/p/3862276.html ...