- 解析request_line 时,使用sscanf (php中也有该函数)
- upstream可以设置upstream代理,如: client要请求phpor.net,tinyproxy中可以配置如果client请求的是phpor.net,则请求proxy.phpor.net,而不是代理请求phpor.net
- remove_connection_headers 中定义了上行请求的请求头中包含的connection要去掉,如: connection,proxy-connection
当tinyproxy遇上php的soap
用例:
- 使用tinyproxy-1.8.3做代理
- php访问soap服务时,使用tinyproxy做代理访问http地址(不是https)
- http响应数据有点儿多,走的是Transfer-Encoding: chunked
问题:
- tinyproxy代理之后,响应头中 HTTP协议版本号为1.1,没有content-length, 也没有connection: close ,也没有Transfer-Encoding: chunked,对于这种尴尬的情况,client端就不方便处理了; curl会有如下警告: no chunk, no close, no size. Assume close to signal end
- 真实原因: curl虽然使用HTTP/1.1方式发送请求,但是tinyproxy对于所有http请求都以HTTP/1.0的方式转发(但是添加了Connection: close 头),最终的openresty(nginx行为也如此)却无视HTTP/1.0,执意返回HTTP/1.1 响应,并且使用Connection: close; tinyproxy直接透传HTTP/1.1 状态行,却丢弃了响应头中的Connection: close;(或许是tinyproxy以为自己总是工作在HTTP/1.0,所以不需要Connection: close 吧)
tinyproxy转发的请求:(发给nginx,nginx再代理转发给后面的openresty)
1 2 3 4 5 |
GET / HTTP/1.0 Host: op-phpor.i.hrbbwx.com Connection: close Accept: */* User-Agent: curl/7.29.0 |
openresty收到的请求:
1 2 3 4 5 |
GET / HTTP/1.0 Host: op-phpor.i.hrbbwx.com Connection: close Accept: */* User-Agent: curl/7.29.0 |
openresty响应:
1 2 3 4 5 |
HTTP/1.1 200 OK Server: openresty/1.9.15.1 Date: Sat, 05 Nov 2016 02:51:16 GMT Content-Type: text/html; charset=UTF-8 Connection: close |
openresty是藏在一个nginx后面的,nginx的响应:
1 2 3 4 5 |
HTTP/1.1 200 OK Server: nginx/1.7.4 Date: Sat, 05 Nov 2016 02:51:16 GMT Content-Type: text/html; charset=UTF-8 Connection: close |
分析:
原本HTTP/1.0 是不支持Host头的,但是很多client还是添加了,很多server也不介意(甚至喜欢)HTTP/1.0协议中使用Host头,参考: http://stackoverflow.com/questions/246859/http-1-0-vs-1-1
Connection 头也是http1.1中定义的,但是tinyproxy也用在了HTTP/1.0中了(难道为了兼容一些不守规矩的server端?),在HTTP/1.0和Connection头的暗示下,server端没有使用Content-length 或 Transfer-encoding也可以理解,也或许正式Connection头的存在,server端才选择响应HTTP/1.1
tinyproxy 源码片段:
tiny proxy发送请求:
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 |
static int establish_http_connection (struct conn_s *connptr, struct request_s *request) { char portbuff[7]; char dst[sizeof(struct in6_addr)]; /* Build a port string if it's not a standard port */ if (request->port != HTTP_PORT && request->port != HTTP_PORT_SSL) snprintf (portbuff, 7, ":%u", request->port); else portbuff[0] = '\0'; if (inet_pton(AF_INET6, request->host, dst) > 0) { /* host is an IPv6 address literal, so surround it with * [] */ return write_message (connptr->server_fd, "%s %s HTTP/1.0\r\n" "Host: [%s]%s\r\n" "Connection: close\r\n", request->method, request->path, request->host, portbuff); } else { return write_message (connptr->server_fd, "%s %s HTTP/1.0\r\n" "Host: %s%s\r\n" "Connection: close\r\n", request->method, request->path, request->host, portbuff); } } |
由于tinyproxy上行的是http/1.0 ,所以会故意将请求头中的connection相关信息去掉,代码如下:
这个函数不仅在process_client_headers 中用到,也在 process_server_headers中用到
解决办法:
- 如果使用隧道代理的方式,tinyproxy就不会做上述多余的处理了,但是, php的soapclient强制写死的逻辑是:如果方式的是https,则使用隧道代理方式,否则,不走隧道代理方式,可是服务提供的就是http,不是https啊!!!!!!
- 修复tinyproxy的这个问题,修复方案:
- 换个proxy
疑问:
- 如果 content-length 不存在与http 1.0,那么http 1.0中的post请求,post数据长度如何表示?(难道也是关闭连接为止?
Docker 端口映射
问题:
如何在已创建的容器上暴露更多端口?
分析:
一般来讲,我们在构建镜像或创建容器的时候指定容器暴露哪些端口,Docker没有提供其他的方法来暴露容器中的端口;
看看Docker暴露端口的手段发现暴露端口这事儿是通过传统的iptables来实现的,于是乎,只需要添加相应的iptables规则就可以搞定了,如:
to expose the container’s port 8000 on your localhosts port 8001:
1 2 |
iptables -t nat -A DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000 |
参考:
http://stackoverflow.com/questions/19897743/exposing-a-port-on-a-live-docker-container
https://www.google.com.hk/?gws_rd=cr,ssl#safe=strict&q=docker+port+mapping+after+run
Docker存储之Devicemapper
问题
docker 容器中创建很大的文件会占用较多的docker存储空间(很正常啊),在容器内部df可以看到容量的变化,在宿主机上docker info也能看到data空间的变化;
当把那个(或那些)很大的文件删除后,在容器内部df可以看到已用容量减小,可用容量变大,但是宿主机上docker info看到的已用空间却没有减少,也就是说,已经分配出去的就收不回来了。
怎么办?
也不是完全回收不了,当把那个容器删除掉,docker info看到的已用空间就会减少了
所以:
- 必要的时候可以重建容器
- 不是特别需要的话,不要在容器内部写太多的数据,大数据写到卷上
帧中继_百度百科
scp 与 软连接
scp的时候,无法做到保留软连接,而总是直接copy软连接的真实内容;
解决办法: 使用 rsync
举例:
1 |
rsync -avuz -e ssh test phpor@172.16.22.41:/tmp/ |
参考: http://www.linuxask.com/questions/how-to-mirror-a-directory-to-a-remote-server-over-ssh
软件可维护性
软件可维护性即维护人员对该软件进行维护的难易程度,具体包括理解、改正、改动和改进该软件的难易程度。
决定可维护性的因素:
1.系统的大小
2.系统的年龄
3.结构合理性
可维护性可通过7个质量特性来衡量:
可理解性
可测试性
可修改性
可靠性
可移植性
可使用性
效率
注意: 没有 可扩展性,可扩展性和可修改性是不同的概念
McCabe度量法_百度百科
nginx 配置点滴
- 重定向
- rewrite可以重定向
- return 301 $url; 也能重定向,简单的重定向使用return 301更简介,如,强制访问443端口,80段定义如下:
123456server {listen 80;server_name phpor.net;return 301 https://$host$request_uri;}
- return 301 $url ; 不同于 return $url ;
- 后者不会导致页面跳转,而是服务器端代为请求了
- location = / 不能嵌套在其他的location中,虽然逻辑上似乎合理,但是执行不到
- nginx中常用的变量: http://nginx.org/en/docs/varindex.html
- lua openresty https://github.com/openresty/lua-nginx-module
关于location:
- location之间是互斥的,可以嵌套,但不可以继承,如:
- location / 嵌套在 location / 中,虽然没有语法错误,但是,内层的location不会被执行到
- location /sub 嵌套在 location / 中时,如果匹配到了location sub 则location / 里面 ,location /sub 外面的逻辑不会被执行到,这就是我所谓的不可以继承,效果等同于并列的两个location
开发库
开发库是开发人员修改代码的地方。(开发人员可以随意修改)
受控库是测试版本代码存放的地方。(需要开发组长提交测试申请修改)
产品库是测试通过版本存放的地方。(需要测试报告来驱动修改)
参考
http://blog.sina.cn/dpool/blog/s/blog_4ec6138401000akg.html?vt=4