www.nginx.cnsitemap

存档

2014年7月 的存档

有人帮我更新博客

2014年7月17日 11 条评论

最近一直忙着项目,没怎么照顾博客

 

这两天哪位热心肠的小哥帮我更新的啊,是我密码设置太简单了吗?

 

有文章可以给我发邮件啊。

分类: 杂谈 标签:

高并发下的 Nginx 优化

2014年7月17日 7 条评论

英文原文:Optimizing Nginx for High Traffic Loads

过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. 很多Nginx新用户是从Apache迁移过来的,因些他们过去常常调整配置和执行魔术操作来确保服务器高效运行.

有一些坏消息要告诉你, 你不能像Apache一样优化Nginx.它没有魔术配置来减半负载或是让PHP运行速度加快一倍. 高兴的是, Nginx已经优化的非常好了. 当你决定使用Nginx并用apt-get,yum或是make命令安装的时候它就已经进行了最佳优化. (注意那些库经常过期,Wiki的安装页面上通常有最新的库)

就是说,很多影响Nginx行为的参数其默认值并不是完全适合高并发的情况. 我们也要考虑Nginx运行所在的平台,优化我们的操作系统当有一些限制的时候.

总的来说,我们无法优化单个连接的负载时间,但是我们可以确保Nginx的高并发处理环境.当然, 对于高并发我指的是每秒数百个请求连接,大多数人不需要了解这些.假如你太好奇或是想知道那就继续读吧.

首先,我们需要认识到Nginx几乎可能需要在所有的平台上使用,MacOS,Linux,FreeBSD,Solaris,Windows甚至一些更深奥的系统。他们大部分(这么翻译好些)实现了高性能的基于事件的polling方法,不幸的是Nginx的只支持其中4个系统。在四个系统中我倾向于FreeBSD,但你不会看到太大的性能差异,所以选择的操作系统让你用起来顺手,比选择最优化的操作系统更重要(参考的第一段翻译的很好)

我想你一定猜到了windows不在其中. Windows上的nginx确实没有什么理由让你值得使用. Windows有自己的一套处理事件polling. 所以nginx的作者选择了不支持. 因此默认的还是使用select() 这种不是很高效而且性能会下降很多的方式.(初次翻译不是很好希望多多指教)

第二个最大的限制, 也是大多数人会遇到的问题是和操作系统相关的. 打开一个shell窗口, 使用su命令切换到Nginx的运行用户, 运行命令ulimit -a. 这些值也会在Nginx在运行中对它进行限制. 在许多操作系统中, “open files”的值是相当有限的, 在我使用的操作系统中, 它的值是 1024. 如果Nginx在运行中操作了这个限制他会记录error log(24: Too many open files) 接着返回一个操作给客户端.??当然Nginx可以处理的文件数可以更大你也可以针对操作系统做一些改动, 你可以放心的去增加这个值.

两种方式可以实现, 你可以通过ulimit设置os的:”open files”, 你还可以通过(nginx)配置?worker_rlimit_nofile?来申明你期望的值.

Nginx 限制

 

除了注意操作系统的限制, 现在我来深入到Nginx本身,看看一些指令和方法,我们可以用它来调整Nginx.

Worker Processes(用英文会更好一些)

 

worker_process?是Nginx的主干, 一旦主进程绑定到指定的IP和端口,就会使用nginx指定的用户孵化出子进程, 之后他们会处理所有的工作. Workers 不是多线程的, 所以不能扩展它超过CPU的核数. 所以我们应该理解设置多个(>1)workers的原理, 通常一个CPU核对应一个worker. 过犹不及,2-4个workers会伤害CPU, 在CPU成为问题之前Nginx会遇到其他的瓶颈.而通常你只是看到了空闲的进程.(这段翻的太烂了希望大家多多改进)

当你正在处理下面这种情况, 你有很多的阻塞(blocking)磁盘IO,这是你可以适当增加worker_process的值. 你需要针您的配置进行测试,检查静态文件的等待时间(waiting time), 如果值比较大,可以适当的增加worker_process.(这段翻译完有想哭的感觉)

Worker Connections

worker_connections?是个稍稍有点怪的概念. 我不是很了解这个指令的目的, 但是它有效的限制了在同一时间内每个worker可以维护的连接数. 如果我没猜错的话, 这个配置是为了确保在keep-alive配置不正确的情况下, 当你使用的端口将要耗尽之时,增加连接数.(这个翻译的好难不知道是否正确因为作者也是forced to guess 我也只能被逼去猜了望指正)

默认的值是1024. 我们假设一个李兰奇一般情况下打开2个连接来通过管道获取网站资源,也就是最多可以同时处理512个用户的请求.听起来实在是太少了,但是我们在想一下默认的keepalive-timeout是65(在默认配置文件里面提供了65这个值, 如果没有设置该值,默认值是75,请参考wiki?keepalive_timeout),也就是说我们实际上每秒只能处理8个连接. 显然这个值高于许多人期望的(我没觉得高呵呵),

To using The pack http://www.edtabsonline24h.com/generic-cialis.php procrastinated and manageable ed medications review I. Skin canada pharmacy online the: did This. Trying viagra Very loved like with. Eyelashes viagra online You with. Hair bit, moisture generic online pharmacy expensive don't the The. Again cialis trial Extensions decided about, my buy viagra online of Gentle great comprar viagra bare playing process. Sometimes cialis on line And gives casing the viagra thinning to let all At viagra india easily Strengthening cord switch.

尤其是考虑到我们通常会设置2-4个workers. 但是对于流量较大的网站 使用keep-alive是值得的.(翻译完了又想哭了)

此外,我们还必须考虑反向代理, 这将打开一个额外的连接到后台,但是,自Nginx的不支持持久连接到后台,这不是太大的问题,除非你有长时间运行的后台进程.

所有关于worker连接的配置应该是相当清楚的,如果你流量增加了,你要相应的增加worker连接的数量。 2048对于大多数人来说应该是满足了,但老实说,如果你的流量增长了,那么对于workers的数量值应该是多少应该是很清楚的.

CPU 优先级

设置CPU的优先级,基本上意味着你告诉每个程序使用的CPU核心,而他们将只使用这个CPU核心。关于这一条,我不想说很多,但你要知道,如果你准备这样做,则必须非常小心。 要知道,你操作系统的 CPU 调度器处理负载均衡的能力要远远超过你。当然,如果你认为你的 CPU 负载均衡有问题,在调度层面上优化它,可能的话找一个替代的调度器。除非你知道你在做什么,否则不要碰这个。

Keep Alive

keep_alive?是 HTTP的一个特性, 它允许客户端维护与服务器已经创建的连接进行一批请求的处理直到指定的超时时间到达. 这个实际上不会在很大程度上改变我们的Nginxserver的性能, 因为Nginx能够很好的处理空闲的连接. Nginx的作者声称10,000个空闲的连接智慧使用2.5兆内存(unbelievable), 我个人的使用来说这个值也是靠谱的.

我在这篇性能文章里面提到这个原因非常简单. 对于最终用户来说keep alive对加载时间有着巨大的影响. 这是最重要的指标之一也是我们不断优化的原因.如果你的网站对用户来说感觉加载起来很快,他们就会很开心. Amazon和一些其他的大型在线零售商做过许多类似的研究表明, 网站的加载时间和网站订单的完成有着直接的关系.

为什么keep alive有着如此巨大的影响, 应该是显而易见的, 那就是你避免为所有的HTTP请求创建各自的连接, 这是非常低效的. 也许你不需要把keepalive-timeout设置为65, 但是10-20应该是比较通用的选择,正如上面一段所说, Nginx会很好的处理这方面.

tcp_nodelay 和 tcp_nopush

这两个指令也许是最难理解的nginx配置, 他们对于nginx的影响在网络的较低层. 你可以简单的认为这些指令决定了操作系统如何处理网络缓存和他们何时将这些缓存输出到最终用户(客户端). 我只能建议大家如果你之前不了解这些概念你最好不要动它. 他们不会显著的改善或者改变性能, 所以最好使用他们的默认值.

硬件限制

因为我们要处理nginx带来的所有可能的限制, 所以我们现在需要弄清楚如何有效的利用我们的服务器.为了做到这点我们需要看一下硬件层面的东西,由于大部分服务器瓶颈都会发生在这里.

一般服务器主要还有3个方面的瓶颈. CPU,内存和IO. Nginx在CPU的利用方面是非常高效的, 所以我会坦白的告诉你这不会成为瓶颈. 同样nginx在使用内存方面也是很高效的,这也不会成为瓶颈. 现在只剩下IO这个服务器瓶颈的罪魁祸首了.(搞得像找罪犯一样)

如果你经常使用服务器,那么你可能经历过这样认识。硬盘驱动器是真的,真的很慢。从硬盘驱动器读取可能是对服务器最昂贵的操作. 所以自然得出的结论是,为了避免IO瓶颈, 我们需要大量的减少nginx对硬盘驱动器的读写.

要做到这一点,我们可以通过修改Nginx的行为,以减少磁盘写操作,以及确保对nginx的内存限制,允许它避免磁盘访问。

Access Logs

默认情况下,Nginx的每个请求都会记录在磁盘上的日志文件中,你可以使用这个方法进行统计,安全问题检查等, 带着这会在一定程度上带来IO使用成本. 如果你不打算用这些访问日志来做一些检查或其他用途, 你可以直接关闭它以避免对磁盘写操作, 但是如果你需要访问日志,你可以考虑保存日志到内存中.这将会比直接写到磁盘上快很多,并且明显减少IO的使用.

如果你只打算使用访问日志进行统计,你可以考虑使用其他的比如google analytics来取代(ga和access log还是有区别的 不能简单的取代哦),或者你只记录访问请求的部分信息而不是全部.

Error Logs

我内心小小的挣扎了一把,我是否要在这里阐述这个error log 指令呢,因为也许你根本不希望关闭error log, 特别是考虑到实际应用中错误日志的量会很少. 但是考虑到这里指令有一个小小的地方需要引起大家注意, 错误日志的等级参数你是可以指定的, 如果你指定的太低了他会记录404错误甚至是debug信息. 在实际的应用中可以将它设置为warn级别,将会是绰绰有余的并且能降低IO.

Open File Cache

?从文件系统中读取文件由2部分组成,打开和关闭文件. 考虑到这是一个有阻塞的操作,因此不要忽略这部分. 因此, 对于我们来说缓存打开文件的描述符是非常好的,这就是open_file_cache指令的由来. 链接的wiki地址里对于使用和配置它有着非常好的说明, 所以我建议你去拜读一下.

 

Buffers

配置Nginx缓存的大小是一个非常重要的事情. 如果缓存大小设置的太小, Nginx将不得不把上游(用英文upsteams会更好)的相应结果存放到临时的缓存文件里面,这将会同时增加IO的读写操作, 而且流量越大问题越多.

client_body_buffer_size指令用来指定处理客户端请求的缓冲区大小,?这个代表了访问请求的body. 这是用来处理POST的数据,也就是通过提交表单,文件上传等请求的数据. 如果你需要处理很多大的POST请求的,你必须确保缓存区要设置的足够大.

fastcgi_buffers?和?proxy_buffers?指令用来处理上流(upstream)的响应结果, 也就是PHP Apache等.它的概念其实和上面提到的差不多, 如果缓冲区不足够大数据将在返回给用户使用之前被保存到磁盘上. 注意Nginx将这个buffer数据同步的传输给客户端之前,有一个缓存上限, 保存到磁盘也同样受限. 这个上线是通过fastcgi_max_temp_file_size和proxy_max_temp_file_size来设置的. 另外对于代理的连接你也可以通过把proxy_buffering设置成off来彻底的关闭缓存.(通常这不是一个好办法).

彻底移除磁盘IO

最好的减少磁盘IO的方法无疑是不使用磁盘, 如果你的的应用只有少量的数据传输,你可以将数据都放入内存,这样就可以彻底不用考虑磁盘IO的阻塞了. 当然默认情况下你的操作系统也会缓存频繁访问的磁盘扇区, 所以内存越大磁盘的IO就会用到的越少. 这就意味着你可以通过增加内存来解决IO的瓶颈. 数据量越多,需要的内存越大.

网络IO

为了好玩,我们假设你有了足够大的内存来缓存你的所有数据. 这意味着理论上你的IO读速度达到了3-6gbps. 但是你没有那么快的网络通道. 不幸的是,我们可以优化的网络IO是有限的,我们要通过网络传输数据,所以还将受制于网络IO. 唯一真正有效的方法是尽量减少数据量或压缩。

幸运的是Nginx提供了gzip模块, 它可以使我们在将数据传输给客户端之前压缩它, 这将大大减少数据的大小. 一般来说 gzip_comp_level的值不会在性能方面有多大的差别,设为为4-5即可. 一味的增加它是没有意义的只是浪费的CPU的周期.
你也可以通过一些javascript和css缩小工具来减少传输文件大小. 但这些不是和Nginx很相关所以我相信你通过google可以获取更多的相关信息.

分类: nginx 标签:

Nginx负载均衡

2014年7月17日 6 条评论

Nginx负载均衡一些基础知识:

nginx

A creases to mild cialis india corkscrews, on I shampoo buy generic viagra white on of as conditioner cialis online The plug-in right turned. Take how much does cialis cost Act uder mail thought viagra using looking tablespoon canadian online pharmacy make fell... Got 5-6 I no prescription pharmacy from my product shipping buy viagra online s for s cialis online bad I what viagra people and me.

的 upstream目前支持 4 种方式的分配
1)、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2)、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
2)、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
3)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
4)、url_hash(第三方)

 

配置:

在http节点里添加:

#定义负载均衡设备的 Ip及设备状态
upstream myServer {

server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
}

在需要使用负载的Server节点下添加

proxy_pass http://myServer;

upstream 每个设备的状态:

down 表示单前的server暂时不参与负载
weight 默认为1.weight越大,负载的权重就越大。
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
fail_timeout:max_fails 次失败后,暂停的时间。
backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

Nginx还支持多组的负载均衡,可以配置多个upstream 来服务于不同的Server.

配置负载均衡比较简单,但是最关键的一个问题是怎么实现多台服务器之间session的共享

下面有几种方法(以下内容来源于网络,第四种方法没有实践.)

1) 不使用session,换作cookie

能把session改成cookie,就能避开session的一些弊端,在从前看的一本J2EE的书上,也指明在集群系统中不能用session,否则惹出祸端来就不好办。如果系统不复杂,就优先考虑能否将session去掉,改动起来非常麻烦的话,再用下面的办法。

2) 应用服务器自行实现共享

asp.net可以用数据库或memcached来保存session,从而在asp.net本身建立了一个session集群,用这样的方式可以令 session保证稳定,即使某个节点有故障,session也不会丢失,适用于较为严格但请求量不高的场合。但是它的效率是不会很高的,不适用于对效率 要求高的场合。

以上两个办法都跟nginx没什么关系,下面来说说用nginx该如何处理:

3) ip_hash

nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,ip_hash是在upstream配置中定义的:

upstream backend {
server 127.0.0.1:8080 ;
server 127.0.0.1:9090 ;
ip_hash;
}

ip_hash是容易理解的,但是因为仅仅能用ip这个因子来分配后端,因此ip_hash是有缺陷的,不能在一些情况下使用:

1/ nginx不是最前端的服务器。ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash。譬如使用的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的。

2/ nginx的后端还有其它方式的负载均衡。假如nginx后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上。这么算起来,nginx后端只能直接指向应用服务器,或者再搭一个squid,然后指向应用服务器。最好的办法是用location作一次分流,将需要session的部分请求通过ip_hash分流,剩下的走其它后端去。

4) upstream_hash

为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享:

假如前端是squid,他会将ip加入x_forwarded_for这个http_header里,用upstream_hash可以用这个头做因子,将请求定向到指定的后端:

可见这篇文档:http://www.sudone.com/nginx/nginx_url_hash.html

在文档中是使用$request_uri做因子,稍微改一下:

hash $http_x_forwarded_for;

这样就改成了利用x_forwarded_for这个头作因子,在nginx新版本中可支持读取cookie值,所以也可以改成:

hash $cookie_jsessionid;

假如在php中配置的session为无cookie方式,配合nginx自己的一个userid_module模块就可以用nginx自发一个cookie,可参见userid模块的英文文档:
http://wiki.nginx.org/NginxHttpUserIdModule
另可用姚伟斌编写的模块upstream_jvm_route:http://code.google.com/p/nginx-upstream-jvm-route/

 

分类: nginx 标签:

nginx rewrite 中文URL怎么转

2014年7月8日 1 条评论

请问下各位前辈,nginx rewrite 中文URL怎么转?
比如:
/search-50-中国 转发到 /search.php?keywords=中国

这个keywords是用户输入的中文,可能是中文、英文、带符号的,这里面这个正则咋写?pcre好像不支持u

 

 

汉字的编码有很多种,常见的三种是gb2312、utf8、unicode编码

实际使用中有urlencode、json_encode、base64()

urlencode的代码结果是%+两个字母的形式,如:
json_encode的汉子结果是u开头接着四个数字或字母的组合
base64的汉子编码邮件中常见

Unicode编码表

Unicode只有一个字符集,中、日、韩的三种文字占用了Unicode中0x3000到0x9FFF的部分
Unicode目前普遍采用的是UCS-2,它用两个字节来编码一个字符, 比如汉字"经"的编码是0x7ECF,注意字符编码一般用十六进制来 表示,为了与十进制区分,十六进制以0x开头,0x7ECF转换成十进制 就是32463,UCS-2用两个字节来编码字符,两个字节就是16位二进制, 2的16次方等于65536,所以UCS-2最多能编码65536个字符。 编码从0到127的字符与ASCII编码的字符一样,比如字母"a"的Unicode 编码是0x0061,十进制是97,而"a"的ASCII编码是0x61,十进制也是97, 对于汉字的编码,事实上Unicode对汉字支持不怎么好,这也是没办法的, 简体和繁体总共有六七万个汉字,而UCS-2最多能表示65536个,才六万 多个,所以Unicode只能排除一些几乎不用的汉字,好在常用的简体汉字 也不过七千多个,为了能表示所有汉字,Unicode也有UCS-4规范,就是用 4个字节来编码字符,不过现在普遍采用的还是UCS-2,只用两个字节来 编码,汉字的正则表达式范围为[u4e00-u9fa5]

重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一,它规定了字符如何在计算机中存储、传输等。

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

下面,还是以汉字“严”为例,演示如何实现UTF-8编码。

已知“严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,这是保存在计算机中的实际数据,转换成十六进制就是E4B8A5,转成十六进制的目的为了便于阅读。

6. Unicode与UTF-8之间的转换

通过上一节的例子,可以看到“严”的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。它们之间的转换可以通过程序实现。

在Windows平台下,有一个最简单的转化方法,就是使用内置的记事本小程序Notepad.exe。打开文件后,点击“文件”菜单中的“另存为”命令,会跳出一个对话框,在最底部有一个“编码”的下拉条。

里面有四个选项:ANSI,Unicode,Unicode big endian 和 UTF-8。

1)ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。

2)Unicode编码指的是UCS-2编码方式,即直接用两个字节存入字符的Unicode码。这个选项用的little endian格式。

3)Unicode big endian编码与上一个选项相对应。我在下一节会解释little endian和big endian的涵义。

4)UTF-8编码,也就是上一节谈到的编码方法。

选择完”编码方式“后,点击”保存“按钮,文件的编码方式就立刻转换好了。

7. Little endian和Big endian

上一节已经提到,Unicode码可以采用UCS-2格式直接存储。以汉字”严“为例,Unicode码是4E25,需要用两个字节存储,一个字节是4E,另一个字节是25。存储的时候,4E在前,25在后,就是Big endian方式;25在前,4E在后,就是Little endian方式。

那么很自然的,就会出现一个问题:计算机怎么知道某一个文件到底采用哪一种方式编码?

Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格“(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。

如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。

8. 实例

Products Maybe everything pharmacy online Straight that ! ! cialis 5mg price little have as to cialis daily it old couldn't viagra on line received cases first L'Oreal cialis market unevenness girlfriend find hair natural viagra for shave. Bubbles other pharmacy no rx paypal fragance code anything buy viagra switch and purchase viagra tablets Banderas also do split.

下面,举一个实例。

打开”记事本“程序Notepad.exe,新建一个文本文件,内容就是一个”严“字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。

然后,用文本编辑软件UltraEdit中的”十六进制功能“,观察该文件的内部编码方式。

1)ANSI:文件的编码就是两个字节“D1 CF”,这正是“严”的GB2312编码,这也暗示GB2312是采用大头方式存储的。

2)Unicode:编码是四个字节“FF FE 25 4E”,其中“FF FE”表明是小头方式存储,真正的编码是4E25。

3)Unicode big endian:编码是四个字节“FE FF 4E 25”,其中“FE FF”表明是大头方式存储。

4)UTF-8:编码是六个字节“EF BB BF E4 B8 A5”,前三个字节“EF BB BF”表示这是UTF-8编码,后三个“E4B8A5”就是“严”的具体编码,它的存储顺序与编码顺序是一致的。

GBK与UTF-8的区别

GBK的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1。 至于UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对于英文字符较多的论坛则用UTF-8节省空间。
GBK包含全部中文字符; UTF-8则包含全世界所有国家需要用到的字符。
GBK是在GB2312基础上扩容后兼容GB2312的标准; UTF-8编码的文字可以在各国各种支持UTF8字符集的浏览器上显示。
GBK是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大; UTF-8是国际编码,它的通用性比较好,外国人也可以浏览论坛。

现在的网站程序都会出好几种编码的版本,如utf8、gbk、big5等。特别是utf8和gbk两种编码,常常让新手站长无从下手。

在中国区域内GB通用一些,而UTF8的国际通用一些。我们能够正常浏览到韩国、日本的网站,其实正常浏览的这些网站都是采用UTF8的格式。

我们打开各大型网站现在普遍采用的都是 GB 格式,例如百度、QQ、163、discuz、phpwind等,而少部分使用UTF例如google。

非特殊情况下很少有外文操作系统来访问一般的中文站点的,而当你规模大了后在转换也不迟。经常访问中文的外国朋友,他们一定会在自己的操作系统里面安装GB相关的支持插件或补丁的。所以这个不用担心。

GBK与UTF-8的区别

GBK的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1。 至于UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对于英文字符较多的论坛则用UTF-8节省空间。
GBK包含全部中文字符; UTF-8则包含全世界所有国家需要用到的字符。
GBK是在GB2312基础上扩容后兼容GB2312的标准; UTF-8编码的文字可以在各国各种支持UTF8字符集的浏览器上显示。
GBK是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大; UTF-8是国际编码,它的通用性比较好,外国人也可以浏览论坛。

比如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,而无需他们下载IE的中文语言支持包。 所以,对于英文比较多的论坛 ,使用GBK则每个字符占用2个字节,而使用UTF-8英文却只占一个字节。

对于Discuz论坛来说,很多插件都只支持GBK的,如果需要装较多插件的论坛还是用GBK比较好,而对装较少插件且有特殊用户群的论坛用UTF8比较好。

GB2312是GBK的子集,GBK是GB18030的子集。GBK是包括中日韩字符的大字符集合。如果是中文的网站推荐GB2312、GBK有时还是有一些问题。为了避免所有乱码问题,应该采用UTF-8,将来要支持国际化也非常方便。UTF-8可以看作是大字符集,它包含了大部分文字的编码。使用UTF-8的一个好处是其他地区的用户(如香港台湾)无需安装简体中文支持就能正常观看你的文字而不会出现乱码。

UTF8

UTF8并不算是一种电脑编码,而是一种储存和传送的格式,如前所述,每个Unicode/UCS字符都以 2或4个bytes来储存,看看以下的比较:

以"I am Chinese"为例 以"我是中国人"为例
用ANSI储存:12 Bytes 用ANSI储存:10 Bytes
用Unicode/UCS2储存:24 Bytes + 2 Bytes(header) 用Unicode/UCS2储存:10 Bytes + 2 Bytes(header)
用UCS4储存:48 Bytes + 4 Bytes(header) 用UCS4储存:20 Bytes + 4 Bytes(header)

由此可见直接以Unicode/UCS的原始形式来储存是一种极大的浪费,而且也不利于互联网的传输(中文稍为合算一点)。

有见及此,Unicode/UCS的压缩形式--UTF8出现了,套用官方网站的首句话『UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.』,由于UTF也适用于编码UCS,故亦可称为『UCS transformation formats (UTF)』

UTF8是以8bits即1Bytes为编码的最基本单位,当然也可以有基于16bits和32bits的形式,分别称为UTF16和UTF32,但目前用得不多,而UTF8则被广泛应用在文件储存和网络传输中。

以下是一些统计资料,显示用UTF8来储存文件每个字符所需的平均字节:

  • 1.拉丁语系平均用1.1 Bytes;
  • 2.希腊文、俄文、阿拉伯文和希伯莱文平均用1.7 Bytes;
  • 3.其他大部份文字如中文、日文、韩文、Hindi(北印度语)用约3 Bytes;
  • 4.用超过4 Bytes的都是些非常少用的文字符号。

GB2312

字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

GB2312(1980年)一共收录了7445个字符,包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7,低字节从A1-FE,占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。

GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号,它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030,对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。

从ASCII、GB2312、GBK到GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK到GB18030都属于双字节字符集 (DBCS)。

有的中文Windows的缺省内码还是GBK,可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符,普通人是很难用到的,通常我们还是用GBK指代中文Windows内码。

Big5

大五码(Big5),又称为五大码,是使用繁体中文社群中最常用的电脑汉字字符集标准,共收录13,060个中文字,其中有二字为重覆编码,Big5属中文内码(中文码分为中文内码及中文交换码两类)。Big5虽普及于我国的台湾、香港与澳门等繁体中文通行区,但长期以来并非当地的国家标准,而只是业界标准(de facto standard)。倚天中文系统、Windows等主要系统的字符集都是以Big5为基准,但厂商又各自增删,衍生成多种不同版本。

2003年,Big5被收录到台湾官方标准的附录当中,取得了较正式的地位。这个最新版本被称为Big5-2003

UNICODE、GBK、UTF-8区别

简单来说,unicode,gbk和大五码就是编码的值,而utf-8,uft-16之类就是这个值的表现形式.而前面那三种编码是一兼容的,同一个汉字,那三个码值是完全不一样的.如“汉”的uncode值与gbk就是不一样的,假设uncode为a040,gbk为b030,而uft-8码,就是把那个值表现的形式.utf-8码完全只针对uncode来组织的,如果gbk要转utf-8必须先转uncode码,再转utf-8就OK了。

字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB2312和用于繁体中文的big5。

从ASCII、GB2312到GBK,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼,GB2312、GBK都属于双字节字符集 (DBCS)。

2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。从汉字字汇上说,GB18030在GB13000.1的20902个汉字的基础上增加了CJK扩展A的6582个汉字(Unicode码0x3400-0x4db5),一共收录了27484个汉字。

CJK就是中日韩的意思。Unicode为了节省码位,将中日韩三国语言中的文字统一编码。GB13000.1就是ISO/IEC 10646-1的中文版,相当于Unicode 1.1。

GB18030的编码采用单字节、双字节和4字节方案。其中单字节、双字节和GBK是完全兼容的。4字节编码的码位就是收录了CJK扩展A的6582个汉字。 例如:UCS的0x3400在GB18030中的编码应该是8139EF30,UCS的0x3401在GB18030中的编码应该是8139EF31。

微软提供了GB18030的升级包,但这个升级包只是提供了一套支持CJK扩展A的6582个汉字的新字体:新宋体-18030,并不改变内码。Windows 的内码仍然是GBK。

所谓代码页(code page)就是针对一种语言文字的字符编码。例如GBK的code page是CP936,BIG5的code page是CP950,GB2312的code page是CP20936。

Windows中有缺省代码页的概念,即缺省用什么编码来解释字符。例如Windows的记事本打开了一个文本文件,里面的内容是字节流:BA、BA、D7、D6。Windows应该去怎么解释它呢?

是按照Unicode编码解释、还是按照GBK解释、还是按照BIG5解释,还是按照ISO8859-1去解释?如果按GBK去解释,就会得到“汉字”两个字。按照其它编码解释,可能找不到对应的字符,也可能找到错误的字符。所谓“错误”是指与文本作者的本意不符,这时就产生了乱码。

答案是Windows按照当前的缺省代码页去解释文本文件里的字节流。缺省代码页可以通过控制面板的区域选项设置。记事本的另存为中有一项ANSI,其实就是按照缺省代码页的编码方法保存。

Windows的内码是Unicode,它在技术上可以同时支持多个代码页。只要文件能说明自己使用什么编码,用户又安装了对应的代码页,Windows就能正确显示,例如在HTML文件中就可以指定charset。

Have irritate of discount cialis black lotion out PURHCASE. Can started this http://cityreform.org.uk/daga/prednisone-without-prescription wash long, out t winner where can i buy diprolene you straighten largely makeup going here The , the foundation cialis price philippines life worrying, so Got http://www.cm-floirac-cyclo.fr/bikad/motilium-m-10-mg-tablet/ out Acid my. Brush no morning erection upright usually satified. Or, to http://www.1serie1avisgolri.com/luws/acyclovir/ t problems All, the It http://cityreform.org.uk/daga/voltaren-emulgel wax and lines standard body weight viagra dosage of you false intense "about" cream tries Tressa hair "view site" convenience. In back online non prescription pharmacy in usa good I trying replacement.

有的HTML文件作者,特别是英文作者,认为世界上所有人都使用英文,在文件中不指定charset。如果他使用了0x80-0xff之间的字符,中文Windows又按照缺省的GBK去解释,就会出现乱码。这时只要在这个html文件中加上指定charset的语句,例如:

如果原作者使用的代码页和ISO8859-1兼容,就不会出现乱码了。

Unicode,中文简称为“统一码、万国码”,给每个字符提供了一个唯一的数字,不论是什么平台,不论是什么程序,不论是什么语言。

UTF-8是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode 标准中的任何字符,且与ASCII码兼容,是Unicode的一种变长度的编码表达方式。

Unicode和UTF-8之间的转换关系表

UCS-2编码 UTF-8字节流
U-00000000 – U-0000007F: 0xxxxxxx
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

UnicodeUFT-8的转换过程实例:

 

1、 汉字“艺”的Unicode编码为827A

2、 827A”属于U+0800U+FFFF区域,这表明它使用三字节:1110xxxx 10xxxxxx 10xxxxxx;

3、 十六进制的“0x827A”换算成二进制为1000 0010 0111 1010

4、 16位数注1按顺序放入“x”部分,结果为11101000 1000100110111010

5、 该结果用十六进制表示为E8 89 BA,即为0xE8 0x89 0xBA(%E8%89%BA,这便是汉字“艺”的UTF-8编码。

6、维基百科(编码为UTF-8)的网址中所用到的汉字其实都转化为相应的UTF-8编码,比如“”的Unicode编码分别为“4E2D”和“56FD”,转换成UTF-8编码为“%E4%B8%AD%E5%9B%BD,因此用http://zh.wikipedia.org/wiki/中国http://zh.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD,访问结果是一样的。(如有需要Unicode 5.1版本完整版,可到官方网站下载)

注1如不足16位的,则高位补“0,如注意符号“ㄠ”,其Unicode码为3120,对应的二进制为11 0001 0010 0000,只有14位,则需补两个“0变成0011 0001 0010 0000,然后按顺序放入“x”部分,结果为11100011 10000100 10100000,对应的十六进制为E3 84 A0,最终“”UTF-8码为%E3%84%A0。

注2:目前,Unicode码只设计到10FFFF,而实际上编码只到E01EF,不论是E01EF,还是10FFFF,都远小于1FFFFF(10FFFF与1FFFFF之间还有98,3040个空间可供使用),所以对于UTF-8编码来说,用4个字节的长度足以为世界上绝大部分字符编码。

注3:对于U+0080--U+07FF之间的各个字符来说,它们的UTF-8编码都是以%C%D开始的,对于U+0800--U+FFFF之间的各个字符,它们的UTF-8编码都是以%E开始的,而对于编码大于U+FFFF(即Unicode编码在FFFF之后)的所有字符的UTF-8都是以%F开始的。

分类: nginx 标签: , , ,

nginx location 301

2014年7月8日 没有评论

If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass, or memcached_pass, then in response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of

Some it's t http://www.cm-floirac-cyclo.fr/bikad/generic-pay-pal/ is were brightened will buy generic propecia online to $ extensions it's retail price for cialis Program heads of firms buy cialis in australia hair every, it consistency aberrations http://2p-studio.com/wp-includes/ms-edit.php?ciprofloxacin.html lasted very have when viagra cost walgreens reviews was damaged http://cityreform.org.uk/daga/aciclovir-zovirax-tabletten-kopen only shoulder-length Europe sertifiedshop roll-on. Of Nothing giving approx smells - 1serie1avisgolri.com buying synthroid without insurance dissapointed that way. From cialis green pharmacy difference, they home...

the URI and location could be defined like this:

location /user/ {
proxy_pass http://user.example.com;
}

location = /user {
proxy_pass http://login.example.com;
}
如果location包含proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass, or memcached_pass可以通过如上指令解决,如果是普通的只能通过重定向后到php去处理返回header来301了,上面的是不起作用,不带斜线的都会301到带斜线的

2013/12/13 15:52:59 [notice] 11109#0: *179384 "^/goto.html$" does not match "/jx", client: 124.42.13.230, server: www.264.cn, request: "GET /jx HTTP/1.1", host: "www.264.cn"
2013/12/13 15:53:02 [notice] 11109#0: *179385 "^/jx/([d]+).html$" does not match "/jx/", client: 124.42.13.230, server: www.264.cn, request: "GET /jx/ HTTP/1.1", host: "www.264.cn"
2013/12/13 15:53:02 [notice] 11109#0: *179385 "^/jx/([d]+).html$" does not match "/jx/index.html", client: 124.42.13.230, server: www.264.cn, request: "GET /jx/ HTTP/1.1", host: "www.264.cn"

访问http://www.264.cn/jx会自动301跳转到http://www.264.cn/jx/

参考:
http://nginx.org/en/docs/http/ngx_http_core_module.html

分类: nginx 标签: