Arganzheng's Blog

stay hungry, stay foolish

Redis的事务

Redis提供了一个乐观锁的事务机制,WATCH-MULTI-EXEC。其作用非常类似于DB的check-and-set(CAS)乐观锁实现: boolean success = false; do{ y = exec_sql("elect a from xxx"); x = y + n; success = exec_sql("udpate a = x where a = y"); } while(!success) 同样的,在Redis中,我们可以这样子实现: boolean success = false; do{ redis.watch('a'); y = redis.get('a'); redis.multi(); redis.set...

nginx URL rewrite自动增加请求参数问题

我们需要将一个URL在服务端进行重定向。比如请求: http://study.arganzheng.me/goto?targetUrl=http%3A%2F%2Freading.arganzheng.me%2Fbook%2Fshare&xxx=yyy,将重定向到targetUrl去:http://reading.arganzheng.me/book/share 去。 那么使用nginx的URL rewrite是很明显的解决方案: location /goto { rewrite ^(.*)$ $arg_targetUrl redirect; } 但是测试发现:http://study.arganzheng.me/goto?targetU...

应用如何记录集中日志

对于分布式系统,提供一个集中式的日志监控平台是非常有必要的,具体参见笔者前面的一片文章:日志监控系统。这里介绍一下客户端要怎么使用。 首先需要配置pom.xml,引入logging-client包: <dependency> <groupId>com.baidu.global.mobile.server.logging.client</groupId> <artifactId>logging-client</artifactId> <version>1.0.0</version> </dependency> 方式一:通过log4j # Remote Log...

kibana学习笔记

配置链接ElasticSearch数据源 If Kibana and Elasticsearch are on the same host, and you’re using the default Elasticsearch port, then you’re all set. Kibana is configured to use that setup by default! If not, you need to edit config.js and set the elasticsearch parameter with the URL (including port, probably 9200) of your Elasticsearch serve...

ElasticSearch如何实现按天翻滚索引

最近在做集中式日志,将应用的日志保存到Elasticsearch中,结合kibana实现集中化日志监控和报警。在设计ES存储的时候。考虑到日志的特殊性,打算采用Daily Indices方式。名称为:log-${application}-YYYY.MM.DD。每天会自动创建一个新的索引,类似于log4j的DailyRollingFileAppender,一来减少活跃索引的大小,二来方便存档和删除。 但是这个不是ES内建的功能,需要应用自己实现,方法有很多种。结合ES提供的功能,最简单的方式是采用如下方式: indices templates 为 log-* 的index应用同样的settings、mappings和alias。 启动 automatic...

Spring MVC的异常处理机制

Spring MVC在找到你的handler之后,会通过反射调用handler的方法: public class InvocableHandlerMethod extends HandlerMethod { /** * Invoke the handler method with the given argument values. */ private Object invoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(getBridgedMethod()); try { return getBridgedMethod().invoke(get...

如何防止表单重复提交

因为安全扫描的问题,它会把线上真实的访问流量进行重放,而且重发时间间隔比较短,导致一个请求变成多次请求,也就是重复提交了。那么怎样解决这个问题呢? 一般来说是通过request token来防止重复提交的。具体实现机制是: 当客户端请求页面时,服务器会通过token标签生成一个随机token,并且将该token放置到全局session当中,然后将该随机数发向客户端;如果客户第一次提交,那么会将该随机数发往服务器端,服务器会接收到该token并且与session中所保存的token进行比较,这时两者的值是相同的,服务器认为是第一次提交,并且将更新服务器端的这个token;如果此时再次重复提交,那么客户端发向服务器端的token还是之前的那个,而服务器端的token...

配置tomcat的access_log

一般应用都是跑在nginx后面,nginx本身就有access_log了,不需要重复配置tomcat的access_log。不过在测试环境,可能是直接访问tomcat。特别是一些别有用心的程序,比如安全扫描程序。 今天就发现一个tomcat应用有很多莫名其妙的请求。看了一下nginx的access_log,没有发现请求日志,但是应用配置的log4j日志确实很多异常的请求日志。于是配置了一下tomcat的access_log,打印一下请求的IP。谷歌了一下,发现配置蛮简单的: <!-- Define the default virtual host Note: XML Schema validation will not work with Xerces 2...

分布式RPC框架如何进行服务寻址和分发

所谓分布式,就是一个服务可能分布在多个Server上。另外,一个Server往往有多个Service,而每个Service有多个方法(服务)。为了对业务透明,服务框架一般会屏蔽远程分布式调用的细节,让用户觉得这就是一个本地服务,也就是说客户端可能就是这样一个调用: String result = HelloService.sayHello(); 至于这个HelloService的sayHello()服务是部署在哪里,它并不关心。但是对于框架,它却需要一定的信息来对这个服务进行寻址和分发。 首先是服务寻址,需要知道XXXService是部署在哪里。也就是说需要得到一个 [<host, port>] 的服务地址列表。然后客户端负载均衡选择一个进行请求...

Quartz突然停止执行问题

现象 线上的API监控系统有一段时间没有发报警邮件了,觉得有点异常,测试同学特意写了一个抛出错误的python校验器,结果发现也是没有收到邮件。 原因 表面现象是没有收到报警邮件,那么有可能是: job没有执行 校验器没有错误:根据前面的验证,可以直接排除。 邮件没有发送 通过在job执行前后打日志,发现一个问题: 有些job只有start日志,没有end日志,也就是说卡住了。然后整个Quartz的QRTZ_FIRED_TRIGGERS表就占满了处于EXECUTING状态的job(我们的Quartz线程池个数配置为8个)。然后线程池空了,没有线程可以执行新的job。 那么job是卡在哪里呢? 通过jstack -l pid发现,所有的...

×