最近搞了个海外的阿里云主机后,就把自己的个人站迁移了。然后就想办法做优化,用上了openresty + php7 + http2。 因为历史原因,自己搞了几个不同的域名,一个是fukun.org,还有一个之前一直用的digdeeply.org,现在想统一起来,可是却发现wordpress里有很多上传附件的时候,链接已经是写死的,使用的当时的域名digdeeply.org,如果去一个一个的把他们替换过来,就不太现实了。 因为自己用过openresty中的lua,所以首先想到的就是使用一个content_by_lua来实现替换,在这个阶段把内容中字符串替换掉,不过有个细节问题就是这里lua拿到的都是nginx的一个一个的chunk,如果想要替换的字符串正好在两个chunk的分界处,那么这个就会被漏掉而不能替换。 然后在查一些资料的时候,突然发现,其实,nginx自己就有支持字符串替换的模块的: sub_filter , 这样就不用自己在lua写了,会更方便一些,那么先来看看sub_filter怎么用吧。 location / { sub_filter ‘https://fukun.org'https://fukun.org'; sub_filter ‘https://fukun.org'https://fukun.org'; sub_filter_once off; } 用法很简单,只要使用 sub_filter ‘search’ ‘replacement’ ,把被替换和替换内容给出来就可以了,可以写多条规则,替换多次。 其它的几个参数稍微看下文档也能明白了: 语法: sub_filter_once on | off; 默认值: sub_filter_once on; 配置段: http, server, location 字符串替换一次还是多次替换,默认替换一次。如果全文中有多个查找到的字符串,希望全部替换的话,就开启这个选项。 语法: sub_filter_types mime-type …; 默认值: sub_filter_types text/html; 配置段: http, server, location 指定需要被替换的MIME类型,默认为“text/html”,如果制定为*,那么所有类型的内容都会被替换,我们其实一般来说,只希望替换text/html中的就可以了,因为如果是图片啥的,你想替换啥呢? 如何安装sub_filter功能模块http_sub_module 以上是sub_filter的用法,但是如果你已经安装好nginx服务了,而且之前没有安装sub_filter模块,那怎么办呢,总不能把nginx全部重新编译重装吧,那样会覆盖之前的nginx配置,还得再来配置一遍。 可以用另外一种方法来更新nginx,那就是只从新编译,而不安装。就是只执行 ./configure 和 make 方法,而不执行make install,这样就不会有问题了。然后把make编译好的nginx二进制文件拷贝到已安装的nginx sbin目录下覆盖之前的,覆盖之前请做好备份,并停止当前运行的nginx。 我是用的openresty,所以很多configure的参数不用自己加,第一次我编译的时候,因为需要http2和status模块, 只执行了: ./configure –prefix=/home/s/apps/openresty-1.9.7.1 –with-http_v2_module –with-http_ssl_module –with-luajit –with-http_stub_status_module 现在需要sub_filter功能,所以只要添加–with-http_sub_module就可以了。那么就是这么编译:
阅读全文

nginx referer限制

语法:valid_referers [none|blocked|server_names]

使用字段:server, location

这个指令在referer头的基础上为 $invalid_referer 变量赋值,其值为0或1。

可以使用这个指令来实现防盗链功能,如果valid_referers列表中没有Referer头的值, $invalid_referer将被设置为1。

参数可以使如下形式:

none 意为不存在的Referer头(表示空的,也就是直接访问,比如直接在浏览器打开一个图片)

blocked 意为根据防火墙伪装Referer头,如:“Referer: XXXXXXX”。

server_names 为一个或多个服务器的列表,0.5.33版本以后可以在名称中使用“*”通配符。

举例:

location /chat/ { 
  valid_referers none blocked so.com *.so.com; 
  if ($invalid_referer) { 
    return 403; 
  } 
} 


阅读全文

最近的谈谈项目使用了部分lua,用于一些请求量超高的请求,在nginx层面挡回去,省的调用大量php进程。

由于以前没用过lua,开发过程中遇到了一些小技能点,记录一下。

1.lua字符串分割函数

--字符串分割函数,按|分割
 function lua_string_split(str, split_char)
     local sub_str_tab = {};
     for mu_id in string.gmatch(str, "(%d+)|*") do
         table.insert(sub_str_tab, mu_id)
     end
     return sub_str_tab;
 end
 --字符串分割函数END

2.使用lua的reids 的 批量获取方法。 比如:hmget

先将所有的field整合到一个Table, 比如: field_table里。

redis:hmget(key,  unpack(field_table))


阅读全文

nginx if判断 and 使用

360图片搜索遇到这么一个场景,pc端的搜索结果页和频道列表页,在移动端访问时,检测到是移动版的ua,会自动跳转到对应的移动端结果页或频道列表页。

现在,pc端新上了一个频道,服饰频道,但是移动端还没开发。当在移动端访问pc版的服饰频道页时,会跳转到移动端的频道页,但是没有服饰频道,所以跳转到了默认的美女频道,体验不好。

所以,就需要做一个处理,当发现是服饰频道时,不跳转,保持pc端的展示。

之前的nginx配置是判断ua后,就决定是否跳转。

if ($http_user_agent ~* "^((.*android.*)|(.*Mobile Safari.*)|(.*windows phone os.*)|acer|zte|lenovo|moto|samu|nokia|sony|kindle|240x320|mobile|mmp|ucweb|midp|pocket|psp|symbian|smartphone|treo    |up.browser|up.link|vodafone|wap)") {
         rewrite "^/$"              http://m.image.so.com/ permanent;
         rewrite "^/([z|i])$"       http://m.image.so.com/$1 permanent;
     }

现在需要对频道页判断,而由于频道页是通过参数传入,而不是在path里边,所以使用rewrite规则无法解决。

其实就可以使用$request_uri判断就可以了。本来是打算在if里通过 and 或者 && 解决,结果发现不支持。

查了资料后,发现一个方便实现的方法,通过两次判断,设置变量的形式。

如下:

if ($http_user_agent ~* "^((.*android.*)|(.*Mobile Safari.*)|(.*windows phone os.*)|acer|zte|lenovo|moto|samu|nokia|sony|kindle|240x320|mobile|mmp|ucweb|midp|pocket|psp|symbian|smartphone|treo    |up.browser|up.link|vodafone|wap)") {
         set $mobile 1;
     }
     if ($request_uri ~* ".*ch=fushi.*"){
         set $mobile 0;
     }
     if ($mobile = 1){
         rewrite "^/$"              http://m.image.so.com/ permanent;
         rewrite "^/([z|i])$"       http://m.image.so.com/$1 permanent;
     }


阅读全文

今天有运营同事反馈在使用一个内部的运营工具时,有些操作失败,后来抓包发现,post到服务端的数据是正常的,在服务端接受到的数据却并不完整,有缺失。很是奇怪。看了下nginx的error log,发现问题所在了,原来是php有设置最大接受变量个数。 2014/04/02 18:06:33 [error] 23623#0: *1115 FastCGI sent in stderr: “PHP message: PHP Warning: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0” while reading response header from upstream, client: 10.18.120.25, 所以,需要做的就是修改下php.ini中的设置:max_input_vars ,默认没有开启,默认值是1000,修改为自己合适的值,就可以了。
阅读全文

首先是必需组件的安装。 有三个,vim的DBGp插件,php的xdebug扩展,Chrome浏览器的xdebug helper扩展。 一: vim 安装 dbgp client 插件 下载 DBGp client $ cd ~/.vim/ $ wget http://www.vim.org/scripts/download_script.php?src_id=7285 -O debugger.zip $ unzip debugger.zip 二:PHP安装xdebug扩展 具体安装方法就不讲了,网上例子很多.官方安装说明. 我把我的配置信息贴出来: sudo vim /home/s/apps/php-5.2.6/etc/include/xdebug.ini [Xdebug] zend_extension=“/home/s/apps/php-5.2.6/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so” xdebug.profiler_enable=0 ;开启profile xdebug.profiler_enable_trigger=1 ;使用触发器开启profile xdebug.profiler_output_dir=“/home/s/logs/xdebugLog” xdebug.auto_trace=0 ;开启trace xdebug.trace_enable_trigger=1 ;使用触发器开启trace xdebug.trace_output_dir=“/home/s/logs/xdebugLog” xdebug.cli_color=1 xdebug.collect_params=2 xdebug.collect_return=on ;remote debug ;开启远程调试 xdebug.remote_enable=1 xdebug.remote_autostart=Off xdebug.remote_port=9000 ;远程端口,不是你web服务的端口,如果没有冲突,一般不用修改。 其中需要注意的是有注释的地方,不自动开启profile和trace,因为这样每次请求都会保存相应信息,会把磁盘爆掉的。把触发器打开,这样,只有在请求的时候带特定信息的时候,才会记录相应的性能信息。触发器的实现机制是:在请求时,如果GET/POST/COOKIE信息中包含特定的变量,会开启对应的debug,profile或trace,所以我们可以通过在web中访问页面时,添加对应的变量来开启相应的功能。如果每次都自己拼接这个,也挺麻烦,所以会介绍后边的xdebug helper的chrome扩展,想开启任何一个功能的时候,点击一下扩展就可以了。也就是说,这个扩展不是调试必须的,但是会让你感觉用起来很方便。 三:chrome扩展xdebug helper 地址:https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc 如果在 chrome://apps里搜索xdebug helper搜索不到,记得把你的语言改为 English. xdebug-helper-introduction20140226142342 xdebug helper两处配置要注意, IDE Key要注意选择Other, 值为1,然后保存。
阅读全文

作者的图片

DigDeeply

Technology Stack: PHP/Openresty/GoLang, and so on…

Web Develop Eneigneer

Beijing China