关闭

Nginx配置与优化

925人阅读 评论(0) 收藏 举报
分类:
1.Nginx  VS Apache
            
       优点:
      1.轻量级,比Apache占用更少的内存和资源
      2.支持更多的并发连接,效率高
      3.Nginx处理请求时异步非阻塞的,而Apache则是阻塞的,在高并发下,Nginx能保持   低资源、低消耗、高性能
      4.高度模块化设计,编写模块相对简单
      5.社区活跃、各种高性能模块方便查到、方便模块扩展
      6.负载均衡性能好
            
       缺点:
      1.rewrite没有Apache强大
      2.动态页面,Nginx处理动态请求较弱,一般动态请求要Apache去做,Nginx只适合静态和反向代理
      3.稳定性没有Apache好
    
      核心区别:
       Apache是同步多进程模型,一个连接对应一个进程;
       Nginx是异步的,多个连接(万级别)可以对应一个进程
       Nginx性能好(epoll),Apache稳定性强
       


2.启动与查看Nginx服务
          1.启动Nginx
                cmd进入Nginx目录执行
                      E:\Nginx\nginx-1.6.3>start nginx
          2.查看Nginx是否启动
                      D:\>tasklist /fi "imagename eq nginx.exe"


                        Image Name                     PID Session Name        Session#    Mem Usage
                        ========================= ======== ================ =========== ============
                        nginx.exe                      896 Console                    1      5,452 K
                        nginx.exe                     5324 Console                    1      5,960 K
                    


       
3.Nginx启动时常见错误:
                          如果启动失败 可以看下logs目录下 error.log 文件里的错误信息
        1.  端口占用问题
                                     我的配置文件里服务侦听的是 80 端口,由于机器上部署了IIS,80端口被默认站点占用,把站点关闭就可以了,这个问题在错误日志里记录是这样的。
            2015/01/15 10:44:12 [emerg] 8800#5988: bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)
                                     碰到类似的错误,请确认端口是否被占用或被防火墙屏蔽
             
        2.Nginx所在目录有中文
                                     错误日志大致输出一下内容
            2015/01/15 11:55:55 [emerg] 5664#8528: CreateFile() "E:\软件\nginx-1.7.8/conf/nginx.conf" failed (1113: No mapping for the Unicode character exists in the target multi-byte code page)
            


4.Nginx的基本配置与优化     ---  /etc/nginx/nginx.conf文件

        
       

基本的 (优化过的)配置

我们将修改的唯一文件是nginx.conf,其中包含Nginx不同模块的所有设置。你应该能够在服务器的/etc/nginx目录中找到nginx.conf。首先,我们将谈论一些全局设置,然后按文件中的模块挨个来,谈一下哪些设置能够让你在大量客户端访问时拥有良好的性能,为什么它们会提高性能。本文的结尾有一个完整的配置文件。

高层的配置

nginx.conf文件中,Nginx中有少数的几个高级配置在模块部分之上。

  • user www-data;
  • pid /var/run/nginx.pid;
  • worker_processes auto;
  • worker_rlimit_nofile 100000;

userpid应该按默认设置 – 我们不会更改这些内容,因为更改与否没有什么不同。

worker_processes 定义了nginx对外提供web服务时的worder进程数。最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。不能确定的时候,将其设置为可用的CPU内核数将是一个好的开始(设置为“auto”将尝试自动检测它)。

worker_rlimit_nofile 更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题了。

Events模块

events模块中包含nginx中所有处理连接的设置。

  • events {
  • worker_connections 2048;
  • multi_accept on;
  • use epoll;
  • }

worker_connections设置可由一个worker进程同时打开的最大连接数。如果设置了上面提到的worker_rlimit_nofile,我们可以将这个值设得很高。

记住,最大客户数也由系统的可用socket连接数限制(~ 64K),所以设置不切实际的高没什么好处。

multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接。

use 设置用于复用客户端线程的轮询方法。如果你使用Linux 2.6+,你应该使用epoll。如果你使用*BSD,你应该使用kqueue。想知道更多有关事件轮询?看下维基百科吧(注意,想了解一切的话可能需要neckbeard和操作系统的课程基础)

(值得注意的是如果你不知道Nginx该使用哪种轮询方法的话,它会选择一个最适合你操作系统的)。

HTTP 模块

HTTP模块控制着nginx http处理的所有核心特性。因为这里只有很少的配置,所以我们只节选配置的一小部分。所有这些设置都应该在http模块中,甚至你不会特别的注意到这段设置。

  • http {
  • server_tokens off;
  • sendfile on;
  • tcp_nopush on;
  • tcp_nodelay on;
  • }

server_tokens 并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。

sendfile可以让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)

tcp_nopush 告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送

tcp_nodelay 告诉nginx不要缓存数据,而是一段一段的发送–当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。

  • access_log off;
  • error_log /var/log/nginx/error.log crit;

access_log设置nginx是否将存储访问日志。关闭这个选项可以让读取磁盘IO操作更快(aka,YOLO)。

error_log 告诉nginx只能记录严重的错误。

  • keepalive_timeout 10;
  • client_header_timeout 10;
  • client_body_timeout 10;
  • reset_timedout_connection on;
  • send_timeout 10;

keepalive_timeout 给客户端分配keep-alive链接超时时间。服务器将在这个超时时间过后关闭链接。我们将它设置低些可以让ngnix持续工作的时间更长。

client_header_timeout 和client_body_timeout 设置请求头和请求体(各自)的超时时间。我们也可以把这个设置低些。

reset_timeout_connection告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。

send_timeout 指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx就会关闭连接。

  • limit_conn_zone $binary_remote_addr zone=addr:5m;
  • limit_conn addr 100;

limit_conn为给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接。

limit_conn_zone设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K*5)32byte状态或者(16K*5)64byte状态。

  • include /etc/nginx/mime.types;
  • default_type text/html;
  • charset UTF-8;

include只是一个在当前文件中包含另一个文件内容的指令。这里我们使用它来加载稍后会用到的一系列的MIME类型。

 

default_type设置文件使用的默认的MIME-type。

charset设置我们的头文件中的默认的字符集。

以下两点对于性能的提升在伟大的WebMasters StackExchange中有解释。

  • gzip_disable "msie6";

    # gzip_static on;
    gzip_proxied any;
    gzip_min_length 1000;
    gzip_comp_level 4;

    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

gzip是告诉nginx采用gzip压缩的形式发送数据。这将会减少我们发送的数据量。

gzip_disable为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容。

gzip_static告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了(想要更详尽的gzip_static的信息,请点击这里)。

gzip_proxied允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。

gzip_min_length设置对数据启用压缩的最少字节数。如果一个请求小于1000字节,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度。

gzip_comp_level设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。我们设置为4,这是一个比较折中的设置。

gzip_type设置需要压缩的数据格式。上面例子中已经有一些了,你也可以再添加更多的格式。

  • # cache informations about file descriptors, frequently accessed files
    # can boost performance, but you need to test those values
    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    ##
    # Virtual Host Configs
    # aka our settings for specific servers
    ##
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

open_file_cache打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。

open_file_cache_valid 在open_file_cache中指定检测正确信息的间隔时间。

open_file_cache_min_uses 定义了open_file_cache中指令参数不活动时间期间里最小的文件数。

open_file_cache_errors指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。

一个完整的配置  

  • user www-data;
    pid /var/run/nginx.pid;
    worker_processes auto;
    worker_rlimit_nofile 100000;

    events {
        worker_connections 2048;
        multi_accept on;
        use epoll;
    }

    http {
        server_tokens off;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;

        access_log off;
        error_log /var/log/nginx/error.log crit;

        keepalive_timeout 10;
        client_header_timeout 10;
        client_body_timeout 10;
        reset_timedout_connection on;
        send_timeout 10;

        limit_conn_zone $binary_remote_addr zone=addr:5m;
        limit_conn addr 100;

        include /etc/nginx/mime.types;
        default_type text/html;
        charset UTF-8;

        gzip on;
        gzip_disable "msie6";
        gzip_proxied any;
        gzip_min_length 1000;
        gzip_comp_level 6;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        open_file_cache max=100000 inactive=20s;
        open_file_cache_valid 30s;
        open_file_cache_min_uses 2;
        open_file_cache_errors on;

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
    }

编辑完配置后,确认重启nginx使设置生效。

  • sudo service nginx restart


Nginx既可作为web server,也可作为反向proxy,这里先讨论作为web server的一般性优化要点。

常用优化要点

nginx使用的是固定数量的workers, 每个worker都处理进入的请求。最佳实践是每个CPU内核配置一个worker.

如何知道您的系统有几个CPU?

  • $ grep ^processor /proc/cpuinfo | wc -l

对于一个四核处理器,配置文件类似:

# One worker per CPU-core.

  • worker_processes  4;
  • events {
  •     worker_connections  8096;
  •     multi_accept        on;
  •     use                 epoll;
  • }
  • worker_rlimit_nofile 40000;
  • http {
  •     sendfile           on;
  •     tcp_nopush         on;
  •     tcp_nodelay        on;
  •     keepalive_timeout  15;
  •     # Your content here ..
  • }

这里我们提高了 worker_connections 设置,定义了每个worker进程能处理多少连接。

服务器的最大连接数量是:

  • worker_processes * worker_connections (= 32384 本例中)

这里启用了 multi_accept,该配置项使nginx能尽快接收尽可能多的请求,减少客户端的连接初始化时间。

最后,本例中使用了 epoll 的事件模型,这也是最佳实践建议。

压缩

很多用户会启用 gzip压缩模块,使得返回客户端的内容更简短,传输更快。

但是压缩会消耗用户服务器资源,通过监控CPU使用率(可采用开源Hyperic),如果过高,可以考虑禁用压缩。

通常只压缩大文件,避免压缩那些压缩效果不好的文件,例如图片,可执行文件等二进制文件。

用户可参考下面配置:

  • gzip  on;
  • gzip_vary on;
  • gzip_min_length 10240;
  • gzip_proxied expired no-cache no-store private auth;
  • gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
  • gzip_disable "MSIE [1-6]\.";

上面配置,只对文件大于10k的文本文件进行压缩。

客户端缓存

如果客户端(一般是浏览器)认为已经保存了要下载的最新内容,就不会向nginx服务器再发请求。

这需要做一些缓存设置。最简单的办法是将所有的图片,js等静态内容设置一个固定的时间长度:

  • location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
  •          access_log        off;
  •          log_not_found     off;
  •          expires           30d;
  •      }

这里我们也禁用了媒体文件的日志,将一些文件后缀文件的过期时间设置为30天。

文件句柄缓存

如果需要处理大量静态文件,需要保持这些文件句柄为打开状态,避免后续再次打开。

下面示例,既可放在nginx配置的 server 部分,也可放在主 http 块中。:

  • open_file_cache          max=2000 inactive=20s;
  • open_file_cache_valid    60s;
  • open_file_cache_min_uses 5;
  • open_file_cache_errors   off;

这里设置服务器最大缓存2000个打开的文件句柄,关闭20秒内无请求的文件句柄,句柄的有效时间是60秒,并且只有访问次数超过5次的才会被缓存。这样只缓存频繁访问的文件,降低文件系统的访问。


实现虚拟主机与证书导入

Nginx的配置文件是比较简洁啦,配置起来也不是那么麻烦

基于IP的虚拟主机

Step 1:准备工作

增加一个网卡地址(原有的是192.168.111.10)

# ifconfig eth0:0 192.168.111.20

建立两个站点目录

# mkdir /website1

# mkdir /website2

建立两个存放日志的目录

# mkdir /var/log/nginx/website1

# mkdir /var/log/nginx/website2

创建两个测试页

# echo "This is website1" >/website1/index.html

# echo "This is website2" >/website2/index.html

Step 2:修改配置文件,原有的配置文件中默认有一个server节点,修改一下,然后再添加一个server节点

server {

listen 192.168.111.10:80;

server_name localhost;

#charset koi8-r;

access_log /var/log/nginx/website1/access.log;

error_log /var/log/nginx/website1/error.log;

location / {

root /website1;

index index.html index.htm;

}

error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

server {

listen 192.168.111.20:80;

server_name localhost;

#charset koi8-r;

access_log /var/log/nginx/website2/access.log;

error_log /var/log/nginx/website2/error.log;

location / {

root /website2;

index index.html index.htm;

}

error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

Step 3:停掉原有的apache服务

# service httpd stop

# /usr/local/nginx/sbin/nginx &

Step 4:在客户机分别访问站点试试

clip_image020

clip_image022

基于主机头的

Step 1:修改配置文件

server {

listen 192.168.111.10:80;

server_name www.website1.com;

#charset koi8-r;

access_log /var/log/nginx/website1/access.log;

error_log /var/log/nginx/website1/error.log;

location / {

root /website1;

index index.html index.htm;

}

error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

server {

listen 192.168.111.20:80;

server_name www.website2.com;

#charset koi8-r;

access_log /var/log/nginx/website2/access.log;

error_log /var/log/nginx/website2/error.log;

location / {

root /website2;

index index.html index.htm;

}

error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

Step 2:修改本机的hosts文件,并重启nginx服务

192.168.111.10 www.website1.com

192.168.111.10 www.website2.com

# pkill nginx

# /usr/local/nginx/sbin/nginx &

Step 3:在浏览器分别输入www.website1.comwww.website2.com试试

clip_image024

clip_image026

完成了吧,下面小编就来实现简单的安全性的访问(使用ssl来控制),这就涉及到证书的创建啦,这里小编将该服务器即作为web服务器,又作为CA服务器,如果作为CA服务器,那么首先的给CA创建证书

Project 5:

Step 1:配置创建证书的配置文件,以及创建证书

# vim /etc/pki/tls/openssl.cnf

45行修改为dir = /etc/pki/CA

clip_image028

clip_image030

根据配置文件的需求创建相关的文件夹和文件

clip_image032

# mkdir certs crl newcerts

# touch index.txt serial

# echo 01 >>serial //初始化文件

创建私钥

# openssl genrsa 1024 >private/cakey.pem

# chmod 600 private/cakey.pem

生成证书文件

clip_image034

Step 2:建立Nginx的安全目录,并生成相关的私钥和证书文件

# mkdir /usr/local/nginx/certs

# cd /usr/local/nginx/certs/

# openssl genrsa 1024 >nginx.key

# chmod 600 nginx.key

因为小编的这台服务器即作为CA又作为web服务器,所以可以证书申请的过程可以直接在本机做

clip_image036

生成证书

clip_image038

Step 3:修改nginx的配置文件,添加用于安全访问的站点

server {

listen 192.168.111.10:443;

server_name www.zzu.com;

ssl on;

ssl_certificate /usr/local/nginx/certs/nginx.cert;

ssl_certificate_key /usr/local/nginx/certs/nginx.key;

ssl_session_timeout 5m;

access_log /var/log/nginx/access.log;

error_log /var/log/nginx/error.log;

ssl_protocols SSLv2 SSLv3 TLSv1;

ssl_ciphers HIGH:!aNULL:!MD5;

ssl_prefer_server_ciphers on;

location / {

root html;

index index.html index.htm;

}

}

Step 4:重启nginx服务,修改客户机的hosts文件并访问

# pkill nginx

# /usr/local/nginx/sbin/nginx &

修改hosts文件

192.168.111.10 www.zzu.com

当首次访问的时候会提示风险

clip_image040

clip_image042

既然没有一个可信任的机构来承认这个证书,那么小编就给一个机构呗,还记得小编最初给这台服务器生成的CA证书吗,web网站的证书就是这个CA发的,如果客户端信任这个CA了,那不就信任web的证书了么,那么就来实现吧,原理是使用证书链,在发送web证书的时候附带将其上级的证书带过去

Step 5:修改web的证书,将CA的证书内容加进去,但是要注意加的顺序,web证书的内容在前,CA证书在后

# cp /etc/pki/CA/cacert.pem /usr/local/nginx/certs

# cd /usr/local/nginx/certs/

# cat cacert.pem >> nginx.cert

重启ngnix服务是必须的

# pkill nginx

# /usr/local/nginx/sbin/nginx &

客户端访问试试

clip_image044

继续

clip_image046

继续

clip_image048

GOON

clip_image050

clip_image052

clip_image054

clip_image056

clip_image058

clip_image060

点击“是”

clip_image062

关闭浏览器重新打开试试

clip_image064



一个nginx.conf配置示例

#user  nobody;
#指定nginx进程数
worker_processes  1;

#全局错误日志及PID文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

 
events {
    # 连接数上限
    worker_connections  1024;
}

#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {

    #设定mime类型,类型由mime.type文件定义
    include       mime.types;
    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 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,    
    sendfile        on;
    #tcp_nopush     on;

    #连接超时时间
    #keepalive_timeout  0;
    keepalive_timeout  65;

    #开启gzip压缩
    #gzip  on;



    #设定负载均衡的服务器列表 支持多组的负载均衡,可以配置多个upstream  来服务于不同的Server.
    #nginx 的 upstream 支持 几 种方式的分配 
    #1)、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
    #2)、weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 跟上面样,指定了权重。
    #3)、ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 
    #4)、fair       
    #5)、url_hash #Urlhash
    upstream mysvr {
      #weigth参数表示权值,权值越高被分配到的几率越大   
      #1.down 表示单前的server暂时不参与负载
      #2.weight 默认为1.weight越大,负载的权重就越大。     
      #3.backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。  
      #server 192.168.1.116  down;
      #server 192.168.1.116  backup;
      server 192.168.1.121  weight=1;
      server 192.168.1.122  weight=2;
    }

    #配置代理服务器的地址,即Nginx安装的服务器地址、监听端口、默认地址
    server {
        #1.侦听80端口 
        listen       80;

        #对于server_name,如果需要将多个域名的请求进行反向代理,可以配置多个server_name来满足要求
        server_name  localhost;
        
        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            # 默认主页目录在nginx安装目录的html子目录。
            root   html;
            index  index.html index.htm;           
            proxy_pass http://mysvr; #跟载均衡服务器的upstream对应   
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        ## 定义错误提示页面
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1090477次
    • 积分:15143
    • 等级:
    • 排名:第797名
    • 原创:416篇
    • 转载:215篇
    • 译文:0篇
    • 评论:139条
    博客专栏
    最新评论