[54chen原创]简单好用的土办法抗击洋鬼子对wordpress系统的广告灌入

54chen

自升级wordpress3.0以后,一切风调雨顺,自上周起,被洋鬼子的广告肉机盯上了,平均每三五分钟一条广告,评论内容大致相同,评论ip来自五湖四海,各不相同。
虽然说akismet是wordpress中antispam无二的选择,但是akismet那个验证码让人很纠结,于是只能自己山寨一把了。 土办法步骤一 转发默认评论地址 常见的洋鬼子的广告肉机,都是利用了wordpress公开的post地址来做到脚本灌入的,其默认地址是wp-comments-post.php,第一步要做的是,怎么这个地址(以nginx为例):
rewrite ^/wp\-comments\-post\.php$ http://www.54chen.com/ last;

土办法步骤二 伪造假地址 既然第一步中的真实地址无法访问了,那第二步肯定是假冒出来可以访问的地址:
if (!-e $request_filename){
rewrite ^/wc([0-9]+)\.html$ /wp-comments-post.php?54chen=$1 last;
}

土办法步骤三 javascript制造假post 完成上面两步之后 ,最后一步就是将原来的comments.php修改post action的地址为伪造的地址,为了更加有效果,使用js来产生随机的wc1234.html即可:
在评论的form中增加onsubmit="chenAntiSpam()" name="commentform";
再增加js:

<script type="text/javascript">
function chenAntiSpam() {
 var param ='wc'+Math.round(Math.random()*1000)+'.html';
 document.commentform.action = 'http://www.54chen.com/'+param;
</script>

大功告成,有效防住了洋鬼子的灌。

[54chen开发日记]注解和拦截器实现权限通用模型的设计实践

54chen ------------------英文大爱-----------------------

        在近期的开发过程中,有使用到拦截器来实现权限控制,使用这种设计方案,可以很好地分离权限与系统本身的功能,让开发过程更加关注系统的核心功能,同时可以很容易做到开发时的任务划分,同时使项目代码的可读性大大提升。先来普及几个相关的名词:

1.AOP:是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面编程,也有叫面向方面编程,不过切面更加形象。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

2.GoF:《Design Patterns: Elements of Reusable Object-Oriented Software》(即《设计模式》一书),由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著(Addison-Wesley,1995)。这几位作者常被称为"四人组(Gang of Four)",而这本书也就被称为"四人组(或 GoF)"书。话说为首的Erich Gamma,在QCon的大会上54chen也有半面之缘。

权限模型的常量定义

        一个系统里最常见的需求莫过于权限、角色,事实上往往这样子的需求和系统本身的功能又是没有太多关联的。按照常规的做法,我们需要两个类,一个表明都有什么权限(例如:删除帖子权限、编辑帖子权限,等等);另一个类表明,各个角色都有什么权限。这样子相当于定义了一个权限和角色模型。

拦截器与注解

        拦截器(Invocation)在在流行的开源框架中很常见,依赖的技术就是Java的动态代理。许多流行的框架都提供实现拦截器的接口,可以很简单就实现一个拦截器,此文不表如何实现。注解(Annotations)是JAVA在5.0后引入的特性,它引入的目的是为了替代一些简单的配置到java代码里,而不用原来的xml。

注解请求示例

        一般的框架,都会有一个controller类,以下用伪代码表示: public class ThreadsController{
@PriCheckRequired({MemberPrivilegeIdentity.CREATE_THREAD})
public String createThread(){
return "createThread";
}
        如代码中所示,一个controller里的一个method对应一个url请求(例中所示为创建帖子)。我们只需要在其方法上标注@PriCheckRequired({MemberPrivilegeIdentity.CREATE_THREAD}),PriCheckRequired就是注解,其传递了一个信息MemberPrivilegeIdentity.CREATE_THREAD,这也就是前文说的权限类中的创建帖子权限。 拦截器工作         拦截器一般都是实现一个框架提供的接口来实现,常用框架都支持。
可以想像在拦截器里要做的事情:

1.根据规定好的request请求的参数,取到用户属于哪个角色。
2.根据controller中注解,取到当前要判断的权限。
3.对比用户角色是否有注解中的权限,如果有,放行,反之拦截。
代码实现 拦截器的代码实现与框架有关:
rose框架如何实现拦截器请看http://code..com/p/paoding-rose/wiki/Rose_Code_Fragment_Interceptor;另外spring等都可以简单实现拦截器。

篇末         这种方式可以做的事情还有许多,例如cache等公共模块的地方,都可以使用,对开发速度、任务划分、代码重用程度都有非常适用的地方。

Rose Pipe–一次对http技术的伟大革新实现(54chen乱弹版)

网站速度一直是互联网公司所关注的核心目标之一,作为SNS网站更是这样。来自世界第一大的打不开的SNS网站的工程师日志中提到,BigPipe: Pipelining web pages for high performance。

原文在外,豆瓣有存根,地址为http://9.douban.com/site/entry/139173635/

来自infoq的一篇资料报道:http://www.infoq.com/cn/news/2010/08/bigpipe--optimize 它本意是充分利用http,将用户感受到的延迟时间降低一半,是如何做到的呢,下面由54chen流水记账一篇解释实现原理。院内曾经由人人网架构师王志亮大侠发表过一篇文章,地址是http://www.54chen.com/architecture/rose-open-source-portal-framework.html,本文将以此例中的项目举例。 HTTP协议 HTTP是一个客户端和服务器端请求和应答的标准,尽管TCP/IP协议是互联网上最流行的应用,HTTP协议并没有规定必须使用它和(基于)它支持的层。 事实上,HTTP可以在任何其他互联网协议上,或者在其他网络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使用。
在这里重新解释HTTP是为了后面做铺垫,一次http访问的过程如下:
1.打开一个连接后,客户机把请求消息送到服务器的停留端口上,完成提出请求动作;
2.服务器在处理完客户的请求之后,要向客户机发送响应消息;
3.客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话。
在使用java的ServletResponse的时候,往往都是如下的作返回结果到用户:

out.write(sb.toString());
out.flush();
out.close();
传统的WEB请求

以图1为例,一个WEB项目往往由不同的部分组成,不同的格局里往往需要从不同的数据表里去取不同的数据。 renren page 图1 人人网公共主页页面

一个用户来访问这个页面,按照传统的做法,其流程图可能是如图2这样的。 54chen:rose pipe 图2 一个传统的http请求过程
在图2中可以看到,一次打开网站页面的过程中,请求发到后端进行了处理(1和2步),只有当后端的取数据作(2步)全部完成的时候,才可能进入第3步,向用户返回组装好的html页。如果说图1中一共有四个模块,对应后台有四条sql语句的话,那么,必须这四条sql语句全部返回了结果,才可能让用户看到页面。

pipe pipe技术充分利用了前后端技术。将一个页面里的多个模块分成不同的window,多线程取数据的作,然后再充分利用http请求的连接,将原来的输出,从一次flush变成多次flush:

out.write(“基础的dom”);
out.flush();
//数据一准备好时
out.write(“js带数据一”);
out.flush();
//数据十二准备好时
out.write(“js带数据二”);
out.flush();
out.close();
其过程如图3所示: 54chen:rose pipe 图3 pipe的请求过程
借用big pipe的代码,第一次是输出的:

<div>
<div id=”left_column”>
<div id=”pagelet_navigation”></div>
</div>
<div id=”middle_column”>
<div id=”pagelet_composer”></div>
<div id=”pagelet_stream”></div>
</div>
<div id=”right_column”>
<div id=”pagelet_pymk”></div>
<div id=”pagelet_ads”></div>
<div id=”pagelet_connect”></div>
</div>
</div>

当有了完整的dom结构时,浏览器就会开始显示没有数据的框架了。

后面的数据每次都以js继续发送到页面中,浏览器收到即开始写入: <script type="text/javascript">
big_pipe.onPageletArrive({id: “pagelet_composer”, content=<HTML>, css=[..], js=[..], …})
</script>

性能 这种显示方式的性能,再借用的图来表示之,如图4: :pipe

使用maven的profiles自动设置log4j线上环境和测试环境区别

程序猿

前言 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具.   如果你已经有十次输入同样的Ant targets来编译你的代码、jar或者war、生成javadocs,你一定会自问,是否有一个重复性更少却能同样完成该工作的方法。Maven便提 供了这样一种选择,将你的注意力从作业层转移到项目管理层。Maven项目已经能够知道如何构建和捆绑代码,运行测试,生成文档并宿主项目网页.
项目的主页地址为:http://maven.apache.org/

深入 Profiles是maven的一个很关键的术语:profile是用来定义一些在build lifecycle中使用的environmental variations,profile可以设置成在不同的环境下激活不同的profile(例如:不同的OS激活不同的profile,不同的JVM激活不同的profile,不同的dabase激活不同的profile等等)。

实例 测试机环境,搞一个文件,比如说/data/test。
线上环境,不搞这个文件。
然后pom在project下如下写法:

<profiles>
<profile>
<id>produce</id>
<activation>
<activeByDefault>false</activeByDefault>
<file>
<missing>/data/test</missing>
</file>
</activation>
<properties>
<log4j.log.path>/opt/logs/xxx.log</log4j.log.path>
<log4j.debug.level>error</log4j.debug.level>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.log.path>/opt/logs/xxx.log</log4j.log.path>
<log4j.debug.level>debug</log4j.debug.level>
</properties>
</profile>
</profiles>
log4j.xml文件设置 为了配合maven的设置属性,需要将log4j中使用的声明用成变量,片段举例:
<logger name="com.xx.xx.xx.xx" additivity="false">
<level value="${log4j.debug.level}"/>
<appender-ref ref="dao"/>
</logger>

<root>
<level value="${log4j.debug.level}"/>
<appender-ref ref="service"/>
</root> 解释 这样,在运行mvn进行build项目的时候,如果线上环境,测试到/data/test文件是missing的,则会激活对应的设置,以此来达到线上环境改成error级别,而测试环境为debug级别。

Sphinx安装配置手记(中文分词54chen支持版)

*从小培养华丽丽的山寨*/> 介绍

Sphinx[英] [sfɪŋks] [美] [sfɪŋks]

出自俄罗斯的开源全文搜索引擎软件Sphinx,单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Coreseek是一款基于Sphinx的开源检索引擎,支持Tb级的全文数据索引,专门为中文用户提供免费开源的中文全文检索系统。

下载

wget http://www.coreseek.cn/uploads/csft/3.2/csft-3.2.12.tar.gz
wget http://www.coreseek.cn/uploads/csft/3.2/mmseg-3.2.12.tar.gz

解压

tar -zxvf mmseg-3.2.12.tar.gz
tar -zxvf csft-3.2.12.tar.gz

中文依赖下载和安装

wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.tar.gz
tar zxvf libiconv-1.13.tar.gz
cd libiconv-1.13/
./configure --with-libiconv-prefix
make
make install

建立系统动态链接

在/etc/ld.so.conf中加一行/usr/local/lib,运行ldconfig。 ld.so.conf和ldconfig是维护系统动态链接库的。真不明白为什么iconv库安装时不把这一步也做了

安装mmseg分词

cd mmseg-3.2.12
yum -y install glibc-common libtool autoconf automake mysql-devel expat-devel
aclocal
libtoolize –force
automake –add-missing
autoconf
autoheader
./configure –prefix=/usr/local/mmseg3
make
make install
cp -f src/*/*.h /usr/local/mmseg3/include/mmseg/

安装sphinx

cd ..
cd csft-3.2.12
aclocal
libtoolize –force
automake –add-missing
autoconf
autoheader
perl -pi -e ’s/lpthread/lpthread -liconv/g’ src/Makefile*
./configure –prefix=/usr/local/coreseek –enable-id64 –without-python –with-mysql –with-mmseg –with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ –with-mmseg-libs=/usr/local/mmseg3/lib/
perl -pi -e ’s/lpthread/lpthread -liconv/g’ src/Makefile*
make
make install
cd /usr/local/coreseek/etc/
cp sphinx.conf.dist csft.conf

修改配置中文支持

vim csft.conf

找到charset_type行,修改为:

charset_dictpath = /usr/local/coreseek/dict/
charset_type = zh_cn.utf-8

生成字典:

cd /root/install/mmseg-3.2.12/data/
/usr/local/mmseg3/bin/mmseg -u unigram.txt
mkdir -p /usr/local/coreseek/dict/
mv unigram.txt.uni /usr/local/coreseek/dict/uni.lib

增加mmseg配置:

vim /usr/local/coreseek/dict/mmseg.ini
mmseg.ini配置:(请将其放置到词典文件uni.lib所在的目录,并在文件结尾空两行)

[mmseg]
merge_number_and_ascii=0; ;合并英文和数字 abc123/x
number_and_ascii_joint=-; ;定义可以连接英文和数字的字符
compress_space=1; ;暂不支持
seperate_number_ascii=0; ;就是将字母和数字打散

索引 touch /data/exceptions.txt
bin/indexer –all

搜中文 bin/search 我爱