-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
81 lines (81 loc) · 23.6 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[Java中enum类型的使用]]></title>
<url>%2F2017%2F10%2F14%2FJava%E4%B8%ADenum%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BD%BF%E7%94%A8%2F</url>
<content type="text"><![CDATA[enum简介java中的enum类型,大家可能都比较了解,可是使用频率并不高,下面直接给出enum类型的写法1234567891011121314151617181920public enum DataSourceEnum{ WebCache("WebCache"), SearchHub("SearchHub"), QueryRewriteServer("QueryRewriteServer") ; private String name; DataSourceEnum(String n){ this.name = n; } public String getName(){ return name; } @Override public String toString(){ return getName(); }} 枚举类型和常量的定义相似,定义了一个独一无二的类型描述符,但是常量有一致性差、类型不安全等缺点,还会造成魔数问题,如果没有注释活着不是开发者很难理解含义 上面的代码,使用时候传入一个枚举的类型,在调用getName()方法获得枚举变量的值 Enum类型提出给JAVA编程带了了极大的便利,让程序的控制更加的容易,也不容易出现错误。心里没有概念之前很难想到如何使用enum,以后在遇到需要控制程序流程时候,多想想是否可以利用enum来实现。 参考资料Java语言中Enum类型的使用介绍 java枚举类型enum的使用]]></content>
<categories>
<category>java</category>
</categories>
<tags>
<tag>enum</tag>
</tags>
</entry>
<entry>
<title><![CDATA[nginx使用uuid跟踪一次完整的请求]]></title>
<url>%2F2017%2F09%2F13%2Fnginx%E4%BD%BF%E7%94%A8uuid%E8%B7%9F%E8%B8%AA%E4%B8%80%E6%AC%A1%E5%AE%8C%E6%95%B4%E7%9A%84%E8%AF%B7%E6%B1%82%2F</url>
<content type="text"><![CDATA[nginx的配置中有一个字段$uuid,这个变量并不是nginx的常量,那为什么可以直接使用它呢,他的作用又是什么呢 uuid的作用Nginx功能很强大,但它还缺少一些常见的功能。 例如,访问日志中经常需要每个请求有唯一ID(UUID),以便可以通过UUID跟踪单个请求在多个服务中的处理流程。 如果发现某个case,可以从nginx中找出该条日志,进而根据UUID可以定位后续一系列服务模块的日志,从而快速定位问题。 uuid如何生成 使用Lua,可自行搜索这个东西,文后也提供了两个链接 自行编写nginx module生成uuid,估计需要深入了解nginx才可得心应手 对如何生成uuid不仔细介绍,请自行搜索或者查看文后的参考文档 uuid的使用生成uuid之后如何使用它,首先再nginx中要先打印出这个uuid来标记这次唯一的请求,后边引用层可以通过不同的方式引用 如果你使用的是proxy模式你可以使用proxy_set_headers 如果你通过fastcgi协议传递给后端的PHP,你可以使用fastcgi_param 也可以使用nginx模块将uuid种在cookie中,后续服务从cookie中读取,在依次传递出去 我们使用的是最后一种方式,注意点是种cookie的时间点不要太长,或者后续服务取到cookie之后就清掉它。 关于排查问题还有一点建议,nginx是反向代理服务器,一台nginx可能打到后端多台服务中的某一台,最好在前端的页面上隐藏的打印出连接关系,方便快速定位日志;这种问题排查方法和app中留一些特殊的后门都是相同的; 参考 Using Lua in Nginx for unique request IDs and millisecond times in logs Nginx Unique Tracing ID 使用nginx + lua 自定义access.log]]></content>
<categories>
<category>nginx</category>
</categories>
<tags>
<tag>nginx uuid</tag>
</tags>
</entry>
<entry>
<title><![CDATA[nginx全局变量]]></title>
<url>%2F2017%2F09%2F03%2Fnginx%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%2F</url>
<content type="text"><![CDATA[经常修改nginx配置,修改过之后,下次可能还需要重新查资料,现在总结一下,方便自己以后查看。先总结下nginx的全局变量。 nginx的全局变量参数解释 $arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。 $args #这个变量等于请求行中(GET请求)的参数,例如from=123&test=1; $binary_remote_addr #二进制的客户地址。 $body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。 $content_length #请求头中的Content-length字段。 $content_type #请求头中的Content-Type字段。 $cookie_COOKIE #cookie COOKIE变量的值,通过该命令可以取到cookie中的任何字段 $document_root #当前请求在root指令中指定的值。 $document_uri #与$uri相同。 $host #请求主机头字段,否则为服务器名称。 $hostname #Set to the machine’s hostname as returned by gethostname $is_args #如果有$args参数,这个变量等于”?”,否则等于””,空值。 $http_user_agent #客户端agent信息 $http_cookie #客户端cookie信息 $limit_rate #这个变量可以限制连接速率。 $query_string #与$args相同。 $request_body_file #客户端请求主体信息的临时文件名。 $request_method #客户端请求的动作,通常为GET或POST。 $remote_addr #客户端的IP地址。 $remote_port #客户端的端口。 $http_x_forwarded_for #网络反访问路径,可能包含多个ip $remote_user #已经经过Auth Basic Module验证的用户名。 $request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。 $request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。 $request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。 $scheme #HTTP方法(如http,https)。 $server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 $server_addr #服务器地址,在完成一次系统调用后可以确定这个值。 $server_name #服务器名称。 $server_port #请求到达服务器的端口号。 $uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。 参考资料如果找不到的全局变量,请参考nginx全局变量]]></content>
<categories>
<category>nginx</category>
</categories>
<tags>
<tag>nginx全局变量</tag>
</tags>
</entry>
<entry>
<title><![CDATA[http中chunked传输协议实际应用]]></title>
<url>%2F2017%2F09%2F03%2Fhttp%E4%B8%ADchunked%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%2F</url>
<content type="text"><![CDATA[分块传输编码简介分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。 通常,HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。通常数据块的大小是一致的,但也不总是这种情况。 原理HTTP 1.1引入分块传输编码提供了以下几点好处 HTTP分块传输编码允许服务器为动态生成的内容维持HTTP持久链接。通常,持久链接需要服务器在开始发送消息体前发送Content-Length消息头字段,但是对于动态生成的内容来说,在内容创建完之前是不可知的. 分块传输编码允许服务器在最后发送消息头字段。对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。没有分块传输编码时,服务器必须缓冲内容直到完成后计算头字段的值并在发送内容前发送这些头字段的值。 HTTP服务器有时使用压缩 (gzip或deflate)以缩短传输花费的时间。分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完成压缩过程以得知压缩后数据的大小。 格式如果一个HTTP消息(请求消息或应答消息)的Transfer-Encoding消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。 每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF (回车及换行),然后是数据本身,最后块CRLF结束。在一些实现中,块大小和CRLF之间填充有白空格(0x20)。 最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段。消息最后以CRLF结尾。 chunked实际应用应用背景本网站是使用nginx+resin的整体架构,使用java开发 应用收益考虑到分片传输可以分片将页面吐出去,考虑先将html中head的部分吐给浏览器,head部分包含公共的js和css,浏览器收到内容后会请求这些资源,而同时前端web程序会开始执行业务逻辑,达到并行的效果,等web程序运行完成再吐一次数据给浏览器,从而达到减少页面加载时间的效果,提高页面的整体加载速度。 应用方案 1.运维同学在nginx上配置,支持chunked协议,在nginx 0.7.66版本之后,有一个配置项chunked_transfer_encoding可以开启或者关闭chunk模式,默认是开启的。 1chunked_transfer_encoding on | off; 2.修改java代码逻辑支持分片发送给浏览器,使用 out.flush();就会将该语句之前的内容发送给浏览器,可以多次使用,在代码的最底部在加上一个,将最后的内容发送出去,每种语言写法不同 PHP: ob_flush(); flush(); perl: STDOUT->autoflush(1); Java: out.flush(); Python: sys.stdout.flush() ruby: stdout.flush 3.修改代业务逻辑放到< /head>之后,< /head>之后flush因此 应用踩坑由于flush之后,再向response中设置任何东西都会失效,比如在业务逻辑中会有设置cookie的逻辑,要把它放到页面中去设值。需要仔细梳理response中的业务逻辑,避免影响广告收入和统计结果 应用效果经过小流量上线试验后,页面加载时间较少150ms,全量上线后,页面加载时间减少200ms,效果比较明显 应用建议如果网站加载时间优化在前端css和js已经优化的没有空间了,可以考虑下这种方案 参考资料 维基百科 http chunked传输]]></content>
<categories>
<category>java</category>
</categories>
<tags>
<tag>chunked</tag>
<tag>加载速度优化</tag>
</tags>
</entry>
<entry>
<title><![CDATA[iframe和父窗口通信]]></title>
<url>%2F2017%2F09%2F02%2Fiframe%E5%92%8C%E7%88%B6%E7%AA%97%E5%8F%A3%E9%80%9A%E4%BF%A1%2F</url>
<content type="text"><![CDATA[之前做过一个需求,合作方要求以iframe的形式将我们的页面嵌入到他们的页面中,就涉及到了iframe和父窗口的通信,一般需要通信的内容就是发送高度,对方接受到信息后设置iframe的高度,保证iframe正常显示,不会遮挡内容也不会出现滚动条。 实现方案 window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全 语法介绍iframe内使用postMessage postMessage(message, targetOrigin, [transfer]); message 将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。 targetOrigin 通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”*“(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。 transfer 可选 是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。 父窗口监听message123456789101112window.addEventListener("message", receiveMessage, false);function receiveMessage(event){ // For Chrome, the origin property is in the event.originalEvent // object. var origin = event.origin || event.originalEvent.origin; if (origin !== "http://example.org:8080") return; // ...} message 的属性有: data 从其他 window 中传递过来的对象。 origin 调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。例如 “https://example.org (implying port 443)”、“http://example.net (implying port 80)”、“http://example.com:8080”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。 source 对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。 实际使用经验 post高度的时候,一般使用document.body.clientHeight获取iframe内的内容的高度 为了快速设置高度,可以在未加载完成的时候,就先post一个高度,等页面onload的时候在post一次高度 注意在页面高度变化的时候需要重新设置高度,页面高度变化一般都是由于发生点击重绘页面,因此点击的时候需要post高度,有时会异步请求一些资源,如果不能在callback中设置高度,可以通过设置定时器不断post高度来解决 postMessage不仅仅是用来设置高度,可以处理任何消息,不要思维定视 参考资料MDN web docs]]></content>
<categories>
<category>js</category>
</categories>
<tags>
<tag>js</tag>
</tags>
</entry>
<entry>
<title><![CDATA[nginx配置详解]]></title>
<url>%2F2017%2F08%2F17%2Fnginx%E9%85%8D%E7%BD%AE%E8%AF%A6%E8%A7%A3%2F</url>
<content type="text"><![CDATA[nginx是一个很强大的高性能Web和反向代理服务器,每次修改nginx配置都需要重新整理查找,因此总结了nginx配置信息,便于以后查阅.本文主要介绍nginx.conf的配置,与具体业务相关的配置不包含在此部分内容中。 nginx.conf的例子123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123#nginx用户组user nobody nobody; #nginx工作进程数worker_processes 8; #nginx可以使用gdb进行调试,Crash的时候产生Core文件#working_directory表示Core文件存放的目录#worker_rlimit_core表示单个worker子进程所使用的Core文件大小的最大值working_directory /test/nginx;worker_rlimit_core 2G;#错误日志error_log logs/error.log error;pid sbin/nginx.pid;#指定进程可以打开的最大描述符:数目。#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除#但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。#现在在Linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。#这是因为nginx调度时分配请求到进程并不是那么的均衡#所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。worker_rlimit_nofile 51200;events{ use epoll; #使用epoll的I/O 模型,感兴趣的可以仔细了解下每个I/O模型的区别 不同操作系统下配置不同 worker_connections 51200; #每个工作进程的最大连接数量 理论上每台nginx服务器的最大连接数为:worker_processes*worker_connections}http{ #nginx通过服务器端文件的后缀名来判断这个文件属于什么类型,再将该数据类型写入HTTP头部的Content-Type字段中,发送给客户端 include mime.types; #nginx默认返回的Content-Type字段 default_type application/octet-stream; #set_real_ip_from指令是告诉nginx,10.0.0.0是我们的反代服务器,不是真实的用户IP,可以包含多行这个配置 set_real_ip_from 10.0.0.0/8; set_real_ip_from 192.168.0.0/16; #当real_ip_recursive为off时,nginx会把real_ip_header指定的HTTP头中的最后一个IP当成真实IP #当real_ip_recursive为on时,nginx会把real_ip_header指定的HTTP头中的最后一个不是信任服务器的IP当成真实IP #当用户访问到我们的网站过程中经过多个路由转发,所以X-Forwarded-For应该是101.10.33.11, 192.168.0.10, #如果设置成off,取到的ip是192.168.0.10,如果设置成on,获得的ip为101.10.33.11,把取得的这个ip当成用户真实的ip real_ip_recursive on; #real_ip_header则是告诉nginx真正的用户IP是存在X-Forwarded-For请求头中 real_ip_header X-Forwarded-For; include xnet.conf; #日志格式 log_format main '$host $remote_addr [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' '$ip2loc_code4 $cookie_SUID $request_time $cookie_SSUID ' '$http_x_forwarded_for $request_length $cookie_YYID '; log_format mini '$time_local $status $body_bytes_sent $request_time $server_name $status $request_uri'; #访问日志打印地址 access_log "logs/${server_name}_access_log" main; access_log logs/status_log mini; #给站点配置多个别名的时候需要配置该选项 server_names_hash_bucket_size 128; #指定客户端请求的http头部缓冲区大小绝大多数情况下一个头部请求的大小不会大于1k不过如果有 #来自于wap客户端的较大的cookie它可能会大于1k,nginx将分配给它一个更大的缓冲区 #这个值可以在large_client_header_buffers里面设置。 #这两个配置只针对get请求,post请求的配置可自行查阅 client_header_buffer_size 32k; large_client_header_buffers 4 32k; #允许客户端请求的最大单文件字节数。如果有上传较大文件,需要设置,防止返回给用户返回413 client_max_body_size 20m; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,减少用户空间到内核空间的上下文切换。 #对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载 sendfile on; #在Linux上使用TCP_CORK套接字选项,关于此字段和下个字段的详解看文后的链接文章 tcp_nopush on; #发送应立即发出的短消息 tcp_nodelay on; #client_header_buffer_size用于指定响应客户端的超时时间。 #这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。 send_timeout 300; #以下两个配置都是http_proxy模块的配置 #nginx跟后端服务器连接超时时间(代理连接超时) proxy_connect_timeout 2; #连接成功后,与后端服务器两个成功的响应操作之间超时时间(代理接收超时) proxy_read_timeout 5; #nginx连接resin采用hmux协议 提高效率 hmux_temp_path /dev/shm/nginx/hmux_temp/; hmux_buffers 4 16k; hmux_connect_timeout 2s; hmux_read_timeout 7s; hmux_send_timeout 6s; hmux_buffer_size 16k; hmux_flush always; #定义路径下默认访问的文件名,一般跟着root放 index index.html index.htm index.shtml; #设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。 #建议设置成大于1k的字节数,小于1k可能会越压越大 gzip_min_length 1000; #gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu) gzip_comp_level 6; #匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。 gzip_types text/plain text/xml application/x-javascript text/css application/xml; #该命令的作用是显示或隐藏掉版本,出现错误的时候看不到nginx的版本信息 server_tokens off; #业务相关的配置独立出来 include vhosts/*.conf;} 整理过程中参考有用的文章 nginx服务器安装及配置文件详解 TCP_NODELAY 和 TCP_NOPUSH The module implements resin’s hmux protocol in nginx Nginx配置文件(nginx.conf)配置详解]]></content>
<categories>
<category>nginx</category>
</categories>
<tags>
<tag>nginx.conf</tag>
</tags>
</entry>
<entry>
<title><![CDATA[windows环境nodejs版本管理]]></title>
<url>%2F2017%2F08%2F12%2Fwindow%E4%B8%8Bnodejs%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86%2F</url>
<content type="text"><![CDATA[由于业务需要使用nodejs,由于nodejs版本更新频繁,为方便使用通过安装nodejs版本管理器来解决这个问题,实验了两种方案,踩过一点小坑,记录一下 nvmw方案nvmw方案是cnode社区上给出的nodejs版本管理方案,尝试按照提示步骤进行,期间遇到了几个问题1nvmw install v6.11.2 提示“没有文件扩展”.js”的脚本引擎”这样的错误,原因是因为JS扩展名的文件被其他软件关联了,需要取消关联。采用的解决方案是:在运行中输入“regedit”进入注册表,把[HKEY_CLASSES_ROOT.js]项下的那个默认值改成”JSFile”就可以正常运行JS 文件了。解决了这个问题之后重新执行命令,又出现新的错误cscript不是内部或外部命令,未找到合适的解决方案,因此寻找新的方案。有成功的例子详见这篇文章 nvm-windows方案此方案比较简单,按照说明安装软件即可,顺利达到目的中间过程中踩了一个坑,在nvm use的命令的时候失效,原因是软件我安装在programe file下了,路径中存在空格,重新安装软件在全英文路径下,安装成功。建议安装路径不要又空格和中文。]]></content>
<categories>
<category>nodejs</category>
</categories>
<tags>
<tag>nodejs</tag>
</tags>
</entry>
</search>