nginx 服务器

2021-05-14 约 5924 字 阅读时长12 分钟

nginx

简介

基于C语言开发开源高性能web服务器和反向代理服务器

反向代理:接受客户端请求,转发请求到真实服务器处理,将处理结果返回客户端

image-20210807162815778

正向代理:访问外部资源时,通过代理服务器去访问

反向代理服务的时服务器,正向代理服务的是客户端

安装及基础命令

安装

bash
 1tar -zxvf nginx-1.20.1.tar.gz
 2cd nginx-1.20.1/
 3
 4# configure 报错时一般缺少一些库,根据提示安装即可
 5# ubuntu: apt-get install libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev make
 6# rocky9: dnf install -y gcc make pcre-devel zlib-devel openssl-devel
 7
 8./configure --prefix=/usr/local/nginx --with-http_ssl_module
 9
10# 编译,建议加上 -j$(nproc) 利用多核加速,编译后的nginx文件在objs里
11make -j$(nproc) 
12
13# 安装,将编译后的文件安装到系统(创建相关目录等)
14make install
15
16# 重新编译时用得上
17# 清除上一次make命令生成的文件
18make clean  

启动

bash
1sbin/nginx		# 普通启动
2sbin/nginx -c conf/nginx.conf	# 通过配置文件启动
3ps -ef | grep nginx		# 查看nginx进程,master和worker两个进程(主进程/工作进程)

关闭

bash
1kill -QUIT 进程id	 # 优雅关闭,等待所有请求处理后关闭
2kill -TERM 进程id	 # 快速关闭,直接杀死

其他命令

bash
1sbin/nginx -c conf/nginx.conf -t	#-t参数,启动时检查配置文件
2sbin/nginx -V	#查看nginx版本号、编译器版本、参数配置
3
4# nginx -s 相关命令,确保 Nginx 已经在运行,并且执行命令的用户有权限读取 Nginx 的 PID 文件(通常位于 /var/run/nginx.pid 或 logs/nginx.pid),该文件记录了主进程的 ID
5sbin/nginx -s reload	# 在不中断服务的情况下,重新加载配置文件 (nginx.conf)
6sbin/nginx -s stop	# 立即终止所有 Nginx 进程(包括主进程和工作进程)。
7sbin/nginx -s quit 	# 通知 Nginx 优雅地关闭服务
8sbin/nginx -s reopen 	# 通知 Nginx 重新打开其日志文件。

默认目录

  • /etc/nginx:nginx配置文件目录, 所有的nginx配置文件都在这里
  • /etc/nginx/nginx.conf:nginx的主配置文件, 可以修改它来改变nginx的全局配置.
  • /etc/nginx/sites-available:这个目录存储每一个网站的"server blocks", nginx通常不会使用这些配置, 除非它们被链接到sites-enabled目录. 一般所有的server block配置都在这个目录中设置, 然后软链接到别的目录
  • /etc/nginx/sites-enabled:这个目录存储生效的"server blocks"配置. 通常, 这个配置都是链接到sites-available目录中的配置文件.
  • /etc/nginx/snippets:这个目录主要可以包含在其它nginx配置文件中的配置片段, 重复的配置都可以重构为配置片段.
  • /var/log/nginx/access.log:每一个访问请求都会默认记录在这个文件中, 除非你做了其它设置.
  • /var/log/nginx/error.log:任何nginx的错误信息都会记录到这个文件中.

nginx配置文件

基础配置

ini
 1#worker进程运行用户
 2#user  nobody;
 3
 4#work进程默认条数,通常为CPU数量两倍或等于CPU数量
 5worker_processes  1;	
 6
 7#配置全局错误日志及类型 [debug|info|notice|warn|error|crit],默认为 error
 8#error_log  logs/error.log  error;
 9
10#配置进程PID文件,存放进程
11#pid        logs/nginx.pid;

events配置

ini
1#配置工作模式和连接数
2events {
3	#一个work进程连接上限,nginx并发连接上线为worker_processes*worker_connections,上限为65535
4    worker_connections  1024;
5}

http配置

ini
 1#配置http服务器,利用它的反向代理实现负载均衡
 2http {
 3	#配置nginx支持可以支持的多媒体类型,/conf/mine.types下可以看见支持的文件
 4    include       mime.types;
 5    
 6    #默认以流形式打开,未识别时
 7    default_type  application/octet-stream;
 8	
 9	#配置asses.log日志格式及存放路径,main是变量名
10    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
11    #                  '$status $body_bytes_sent "$http_referer" '
12    #                  '"$http_user_agent" "$http_x_forwarded_for"';
13	
14	#配置asses.log日志存放路径
15    #access_log  logs/access.log  main;
16
17	#开启高效文件传输模式
18    sendfile        on;
19    #防止网络阻塞
20    #tcp_nopush     on;
21	
22	#长连接超时时间
23    keepalive_timeout  65;
24	
25	#开启gzip压缩输出
26    #gzip  on;
27
28	#虚拟主机,一个http配置可以有多个server,端口号和域名不能完全一致
29    server {
30    	#端口号
31        listen       80;
32        #域名
33        server_name  localhost;
34
35		#编码格式,默认为utf-8
36        #charset koi8-r;
37		
38		#访问日志,访问这个server主机时输出日志
39        #access_log  logs/host.access.log  main;
40		
41		#默认的匹配 / 处理,当访问中有 / 时(/ 根路径),匹配到该location处理
42        location / {
43        	#本地磁盘的根路径
44            root   html;
45            #默认欢迎页
46            index  index.html index.htm;
47        }
48		
49		#配置错误页
50        #error_page  404              /404.html;
51        # redirect server error pages to the static page /50x.html
52        #配置50x错误页面
53        error_page   500 502 503 504  /50x.html;
54        
55        #精准匹配,
56        location = /50x.html {
57            root   html;
58        }
59
60        # deny access to .htaccess files, if Apache's document root
61        # concurs with nginx's one
62        #
63        #location ~ /\.ht {
64        #    deny  all;
65        #}
66    }
67	#这里可以继续配置其他server虚拟主机
68}

Location 详解

基本语法

ini
1location [修饰符] /匹配路径 {
2    # 处理规则(如 proxy_pass、root、rewrite 等)
3}
  • 修饰符:决定匹配方式(可选,无修饰符为默认匹配);
  • 匹配路径:要匹配的 URI 路径(支持字符串、正则表达式);
  • 块内指令:匹配成功后执行的操作(如 rootproxy_passreturn 等)。

location 的匹配优先级由修饰符决定,优先级从高到低 如下:

修饰符匹配类型说明
=精确匹配严格匹配 URI 全路径,匹配成功立即终止后续匹配
^~前缀匹配(非正则)匹配 URI 前缀,优先级高于正则匹配,匹配成功终止后续正则匹配
~正则匹配(区分大小写)按配置顺序匹配正则表达式,第一个匹配成功即生效
~*正则匹配(不区分大小写)~ 类似,但忽略大小写
无修饰符普通前缀匹配匹配 URI 前缀,优先级最低,最终会选择最长匹配的路径

关键注意事项

  1. proxy_pass 末尾斜杠的坑;proxy_pass 末尾是否加 /,会影响 URI 的拼接规则

    ini
     1# 场景1:location 路径以 / 结尾,proxy_pass 不加 /
     2location /api/ {
     3    proxy_pass http://127.0.0.1:8080;
     4    # 请求 /api/user → 转发到 http://127.0.0.1:8080/api/user
     5}
     6
     7# 场景2:location 路径以 / 结尾,proxy_pass 加 /
     8location /api/ {
     9    proxy_pass http://127.0.0.1:8080/;
    10    # 请求 /api/user → 转发到 http://127.0.0.1:8080/user(去掉 /api/ 前缀)
    11}
  2. 正则匹配的顺序;~/~* 按配置文件中出现的顺序匹配,第一个匹配成功即生效,因此需将更具体的正则写在前面

    ini
    1# 错误:先匹配通用正则,导致 /api/v2/ 永远匹配不到
    2location ~ /api/ { ... }
    3location ~ /api/v2/ { ... }
    4
    5# 正确:先匹配具体正则
    6location ~ /api/v2/ { ... }
    7location ~ /api/ { ... }
  3. 大小写敏感

    • 系统层面:Linux 文件系统区分大小写(如 index.HTMLindex.html 是不同文件);
    • Nginx 层面:~ 区分大小写,~* 不区分,无修饰符的前缀匹配区分大小写。

静态网站部署

  1. 修改配置文件,添加一个匹配,绑定根目录到自己的目录

    ini
    1location / {
    2    root   /usr/share/nginx/html;
    3    index  index.html index.htm;
    4}
    5location /myweb {
    6    root  /home/html;
    7    index index.html index.htm;
    8}
  2. root指定的时 / 路径,所以需要在/home/html下创建myweb目录

  3. 重启nginx:nginx -s reload

负载均衡

原理图统一入口nginx

image-20210807231614382

基本配置

location拦截 /myweb 请求,proxy_pass 然后转发到 upstream 中处理

ini
1upstream myweb {
2	server 192.168.115.128:8081;
3	server 192.168.115.128:8082;
4}
5server{
6	location /myweb {
7		proxy_pass http://myweb;
8    }
9}

负载均衡策略

  1. 轮询(默认)

    ini
    1#轮流发给每个服务器
    2upstream myweb {
    3	server 192.168.115.128:8081;
    4	server 192.168.115.128:8082;
    5}
  2. 权重策略

    ini
    1#按照权重,如下:3个请求,一个服务器处理2个,另个服务器处理1个
    2upstream myweb {
    3	server 192.168.115.128:8081	weight=2;
    4	server 192.168.115.128:8082	weight=1;
    5}
  3. ip hash

    ini
    1#根据ip值hash,相同的ip总是访问同一个服务器,不会丢失session,但是不建议使用,可能存在所有请求在一个服务器
    2upstream myweb {
    3	ip_hash;
    4	server 192.168.115.128:8081;
    5	server 192.168.115.128:8082;
    6}
  4. 最少连接数

    ini
    1#转发请求到处理请求最少的服务器
    2upstream myweb {
    3	least conn;
    4	server 192.168.115.128:8081;
    5	server 192.168.115.128:8082;
    6}

其他配置

  1. 备份

    ini
    1#在非backup服务器全部宕机时,请求转发到backup服务器,版本更新时可用
    2upstream myweb {
    3	server 192.168.115.128:8081;
    4	server 192.168.115.128:8082 backup;
    5}
  2. down

    ini
    1#标记down的服务器不参与负载均衡
    2upstream myweb {
    3	server 192.168.115.128:8081;
    4	server 192.168.115.128:8082 down;
    5}

静态代理

静态资源由nginx处理,通过拦截静态资源的请求,进行相应的处理

实现方式一,在 location 中配置静态资源的后缀,拦截请求后缀名

ini
1location ~.*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|f;v|mid|doc|ppt|pdf|xlx|mp3|wma)$ {
2	   root /opt/static;
3}

实现方式二,在 location 中配置静态资源所在目录实现,拦截请求路径

ini
1location ~.*/(css|js|img|images) {
2	root /opt/static;
3}

动静分离

整体架构图架构图

image-20210808121655129

实现

  • nginx负载均衡服务器

    ini
     1upstream myweb {
     2	ip_hash;
     3	server 192.168.115.128:8081;
     4	server 192.168.115.128:8082;
     5}
     6upstream static {
     7	server 192.168.115.128:81;
     8	server 192.168.115.128:82;
     9}
    10server{
    11	location /myweb {
    12		proxy_pass http://myweb;
    13    }
    14    location ~.*/(css|js|img|images) {
    15		proxy_pass http://static;
    16	}
    17}
  • 配置存放静态资源的nginx服务器

    ini
    1location ~.*/(css|js|img|images) {
    2	root /opt/static;
    3}

虚拟主机

基于端口(不重要)

ini
 1server {
 2    #端口号
 3    listen       80;
 4    #域名
 5    server_name  localhost;
 6    location / {
 7    root   html;
 8    index  index.html index.htm;
 9    }
10    error_page   500 502 503 504  /50x.html;
11    location = /50x.html {
12    root   html;
13    }
14}
15server {
16    #端口号
17    listen       81;
18    #域名
19    server_name  localhost;
20    location / {
21    root   html;
22    index  index.html index.htm;
23    }
24    error_page   500 502 503 504  /50x.html;
25    location = /50x.html {
26    root   html;
27    }
28}

基于域名(重要)

ini
 1server {
 2    #端口号
 3    listen       80;
 4    #域名
 5    server_name  www.myweb1.com;
 6    location / {
 7    root   html;
 8    index  index.html index.htm;
 9    }
10    error_page   500 502 503 504  /50x.html;
11    location = /50x.html {
12    root   html;
13    }
14}
15server {
16    #端口号
17    listen       80;
18    #域名
19    server_name  www.myweb2.com;
20    location / {
21    root   html;
22    index  index.html index.htm;
23    }
24    error_page   500 502 503 504  /50x.html;
25    location = /50x.html {
26    root   html;
27    }
28}

示例

配置示例

nginx
  1server {
  2    listen 80;
  3    server_name shop.example.com;
  4    root /var/www/shop;
  5
  6    # ==========================================
  7    # 1. 精确匹配 (=) - 最高优先级
  8    # ==========================================
  9
 10    # 首页精确匹配 - 加快首页访问速度
 11    location = / {
 12        return 200 "欢迎来到首页 [精确匹配 =]";
 13        add_header Content-Type text/plain;
 14    }
 15
 16    # robots.txt 精确匹配
 17    location = /robots.txt {
 18        return 200 "User-agent: *\nDisallow: /admin/";
 19        add_header Content-Type text/plain;
 20    }
 21
 22    # favicon.ico 精确匹配
 23    location = /favicon.ico {
 24        log_not_found off;
 25        access_log off;
 26        expires 30d;
 27    }
 28
 29
 30    # ==========================================
 31    # 2. 前缀优先匹配 (^~) - 阻止正则匹配
 32    # ==========================================
 33
 34    # 静态资源目录 - 不需要正则处理,直接命中提高性能
 35    location ^~ /static/ {
 36        alias /var/www/shop/static/;
 37        expires 30d;
 38        add_header Cache-Control "public, immutable";
 39        return 200 "静态资源目录 [前缀优先 ^~]";
 40    }
 41
 42    # 上传文件目录
 43    location ^~ /uploads/ {
 44        alias /var/www/shop/uploads/;
 45        expires 7d;
 46        return 200 "上传文件目录 [前缀优先 ^~]";
 47    }
 48
 49    # 阻止访问隐藏文件
 50    location ^~ /. {
 51        deny all;
 52        return 403 "禁止访问隐藏文件 [前缀优先 ^~]";
 53    }
 54
 55
 56    # ==========================================
 57    # 3. 正则匹配 (~ ~*) - 按顺序匹配
 58    # ==========================================
 59
 60    # 图片文件处理 (区分大小写)
 61    location ~ \.(jpg|jpeg|png|gif|webp|svg|ico)$ {
 62        expires 30d;
 63        add_header Cache-Control "public";
 64        return 200 "图片文件 [正则匹配 ~]";
 65    }
 66
 67    # CSS/JS 文件处理 (不区分大小写)
 68    location ~* \.(css|js)$ {
 69        expires 7d;
 70        add_header Cache-Control "public";
 71        return 200 "CSS/JS文件 [正则不区分大小写 ~*]";
 72    }
 73
 74    # 字体文件处理
 75    location ~* \.(ttf|woff|woff2|eot)$ {
 76        expires 365d;
 77        add_header Cache-Control "public, immutable";
 78        add_header Access-Control-Allow-Origin *;
 79        return 200 "字体文件 [正则不区分大小写 ~*]";
 80    }
 81
 82    # 视频文件处理
 83    location ~* \.(mp4|webm|ogg|avi)$ {
 84        expires 30d;
 85        add_header Cache-Control "public";
 86        return 200 "视频文件 [正则不区分大小写 ~*]";
 87    }
 88
 89    # PHP 文件处理 (演示正则顺序重要性)
 90    location ~ \.php$ {
 91        # fastcgi_pass unix:/var/run/php-fpm.sock;
 92        # fastcgi_index index.php;
 93        return 200 "PHP文件处理 [正则匹配 ~]";
 94    }
 95
 96    # 禁止访问备份文件
 97    location ~ \.(bak|backup|old|tmp)$ {
 98        deny all;
 99        return 403 "禁止访问备份文件 [正则匹配 ~]";
100    }
101
102
103    # ==========================================
104    # 4. 普通前缀匹配 - 最长匹配原则
105    # ==========================================
106
107    # API 接口 v2 (更长的前缀)
108    location /api/v2/ {
109        proxy_pass http://backend_v2;
110        return 200 "API v2接口 [普通前缀,更长]";
111    }
112
113    # API 接口 v1 (较短的前缀)
114    location /api/v1/ {
115        proxy_pass http://backend_v1;
116        return 200 "API v1接口 [普通前缀,较短]";
117    }
118
119    # API 接口通用
120    location /api/ {
121        proxy_pass http://backend;
122        return 200 "API通用接口 [普通前缀,最短]";
123    }
124
125    # 商品详情页
126    location /product/ {
127        try_files $uri$uri/ /product/index.html;
128        return 200 "商品详情页 [普通前缀]";
129    }
130
131    # 用户中心
132    location /user/ {
133        try_files $uri$uri/ /user/index.html;
134        return 200 "用户中心 [普通前缀]";
135    }
136
137    # 管理后台
138    location /admin/ {
139        auth_basic "Admin Area";
140        auth_basic_user_file /etc/nginx/.htpasswd;
141        return 200 "管理后台 [普通前缀]";
142    }
143
144
145    # ==========================================
146    # 5. 通用匹配 - 兜底规则
147    # ==========================================
148
149    # 所有其他请求
150    location / {
151        try_files $uri$uri/ /index.html;
152        return 200 "通用匹配 [兜底规则]";
153    }
154}

反向代理配置示例

nginx
  1# ========================================
  2# 第一部分:全局块 (Main Block)
  3# ========================================
  4
  5# 1. 配置运行 Nginx 服务器的用户(组)
  6# user  nobody;
  7
  8# 2. 允许生成的 worker process 数
  9# 优化建议:设置为 auto,自动根据 CPU 核心数生成进程,充分利用多核性能
 10worker_processes auto;
 11
 12# 3. 全局错误日志路径与级别
 13# error_log  logs/error.log;
 14# error_log  logs/error.log  notice;
 15# error_log  logs/error.log  info;
 16
 17# 4. 进程 PID 存放路径
 18# pid        logs/nginx.pid;
 19# 5. 单个 worker 进程可打开的最大文件描述符数(高并发必配)
 20# 优化建议:需配合系统级 ulimit -n 设置,防止高并发下报 "too many open files"
 21worker_rlimit_nofile 65535;
 22
 23
 24# ========================================
 25# 第二部分: events 块
 26# ========================================
 27events {
 28    # 1. 单个 worker process 支持的最大连接数
 29    # 优化建议:根据内存和系统文件句柄限制适当调大(如 10240 或 65535)
 30    worker_connections 10240;
 31
 32    # 2. 使用高效的事件驱动模型
 33    # 优化建议:Linux 系统下开启 epoll,大幅提升高并发处理能力
 34    # use epoll;
 35
 36    # 3. 允许一个 worker 进程同时接受多个新连接
 37    multi_accept on;
 38}
 39
 40
 41# ========================================
 42# 第三部分: http 块
 43# ========================================
 44http {
 45    # 1. 文件引入与 MIME-TYPE 定义
 46    include mime.types;
 47    default_type application/octet-stream;
 48
 49    # 2. 自定义日志格式
 50    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 51    '$status $body_bytes_sent "$http_referer" '
 52    '"$http_user_agent" "$http_x_forwarded_for"';
 53
 54    # access_log  logs/access.log  main;
 55
 56    # ========================================
 57    # 性能优化核心配置
 58    # ========================================
 59    # 3. 开启高效文件传输模式(零拷贝)
 60    sendfile on;
 61    # 配合 sendfile 使用,防止网络阻塞,减少报文段数量
 62    tcp_nopush on;
 63    # 禁用 Nagle 算法,适用于实时性要求高的场景(与 tcp_nopush 互斥,视业务而定)
 64    # tcp_nodelay   on;
 65
 66    # 4. 长连接超时时间(单位:秒)
 67    # 优化建议:减少频繁 TCP 三次握手的开销
 68    keepalive_timeout 65;
 69    # 单个长连接上允许的最大请求数
 70    keepalive_requests 1000;
 71
 72    # 5. 开启 Gzip 压缩
 73    # 优化建议:显著减少纯文本资源(HTML/CSS/JS)的传输体积,节省带宽
 74    gzip on;
 75    gzip_min_length 1k; # 小于 1k 的资源压缩收益不大,不压缩
 76    gzip_comp_level 6; # 压缩级别 1-9,6 是性能与压缩率的较好平衡
 77    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
 78
 79    # 6. 隐藏 Nginx 版本号(安全加固)
 80    server_tokens off;
 81
 82    # 7. 限制客户端请求体大小(防止恶意大文件上传攻击)
 83    client_max_body_size 10M;
 84
 85
 86    # ========================================
 87    # Server 块(虚拟主机配置)
 88    # ========================================
 89    server {
 90        listen 80;
 91        server_name 127.0.0.1;
 92
 93        # 当前虚拟主机访问日志
 94        access_log logs/host.access.log main;
 95
 96        # 基础安全响应头(可选,增强防点击劫持等安全性)
 97        # add_header X-Frame-Options "SAMEORIGIN";
 98        # add_header X-Content-Type-Options "nosniff";
 99
100        # location 指令说明, 该指令用于匹配 URL, 语法如下:
101        # nginx有两层指令来匹配请求 URI 。第一个层次是 server 指令,它通过域名、ip 和端口来做第一层级匹配,当找到匹配的 server 后就进入此 server 的 location 匹配。
102        # location [ = | ~ | ~* | ^~] uri {
103        #       ..............
104        # }
105        # =:用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配, 如果匹配成功,就停止继续向下搜索并立即处理该请求。
106        # ~:用于表示 uri 包含正则表达式,并且区分大小写。
107        # ~*:用于表示 uri 包含正则表达式,并且不区分大小写。
108        # ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求
109        # 字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location块中的正则 uri 和请求字符串做匹配。
110        # 注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识
111        # 如果proxy_pass末尾有斜杠/,proxy_pass不拼接location的路径
112        # 如果proxy_pass末尾无斜杠/,proxy_pass会拼接location的路径
113        # 反向代理配置
114        location /cgsp_back/ {
115            # proxy_pass 说明:
116            # 末尾有斜杠 /,proxy_pass 不拼接 location 的路径
117            # 末尾无斜杠 /,proxy_pass 会拼接 location 的路径
118            proxy_pass http://127.0.0.1:8080;
119
120            # 重写 Cookie 路径(解决后端 Set-Cookie 路径不匹配问题)
121            proxy_cookie_path ~^[^/](.*)$ /cgsp_back;
122
123            # 传递真实客户端信息给后端服务器
124            proxy_set_header Host $host;
125            proxy_set_header X-Real-IP $remote_addr;
126            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
127
128            # 代理超时设置(防止后端响应过慢导致 Nginx 长时间等待)
129            proxy_connect_timeout 3s;
130            proxy_read_timeout 10s;
131
132            # 单独记录反向代理的访问日志
133            access_log logs/access-cgsp_back.log main;
134        }
135    }
136
137
138    # ========================================
139    # HTTPS 配置模板(按需启用)
140    # ========================================
141    # server {
142    #    listen       443 ssl http2; # 开启 HTTP/2 可进一步提升加载速度
143    #    server_name  localhost;
144    #
145    #    ssl_certificate      cert.pem;
146    #    ssl_certificate_key  cert.key;
147    #
148    #    # SSL 会话缓存优化(减少 TLS 握手开销)
149    #    ssl_session_cache    shared:SSL:10m;
150    #    ssl_session_timeout  10m;
151    #
152    #    ssl_ciphers  HIGH:!aNULL:!MD5;
153    #    ssl_prefer_server_ciphers  on;
154    #
155    #    location / {
156    #        root   html;
157    #        index  index.html index.htm;
158    #    }
159    # }
160}
使用滚轮缩放
按住拖动