Record

机会是留给有准备的人

团队的建立

无论开会,还是聊天老大一再强调团队的文化:

服务意识,崇尚行动,负责到底。


一开始并没觉得这句话的有多大力量,估计很多人都只是记得这话,但实际行动起来并不会有多上人记得
但看到老大一步步主动推动事情都能顺利的完成。可谓功力深厚啊
譬如他提到他是如何推动羽毛球俱乐部的建立的。
其实一开始公司本来就给员工提供去打羽毛球的资金,但是没人牵头,很快就没人去打了
而研发部愿意去打羽毛球的还是很多的。于是他为了推动俱乐部的成立,先找2个人带头组织开始
先在研发部号召参加,这是要交会费的,免费大家就可能随便起来,约好的就可能不去了,
交了会费大家才会比较珍惜。其他部们想参加还要贵点(哈哈),就这样越来越多人参加了。
俱乐部由此成立。

玩游戏有感

最近看到2048的游戏很火,看老婆,看同事都在玩,而且玩的不亦乐乎。于是自己就体验了一把。
游戏看似简单,但刚开始一般最多玩到1024,很难玩到2048,但经同事说有规律可循,不要往上移动就可。
但是玩了几次才发现,不只是不要往上移动,还要最大的数字保持在一个角落,数字尽可能从大到小排列。
然后就是随机应变。发现这规律过,就基本能轻松玩过2048,甚至更高的数字。
生活工作也应多考虑多寻规律以免做许多吃力的事情。

组织开发抢购活动

最近负责组织开发抢购活动,刚听到都有些小紧张啊,因之前公司搞的大型秒杀抢购都是遇到某系统挂了,但是看过老大搞的秒杀抢购的代码,心中还是有点数的,只是没实战过。这次终于有机会了。然后开始...

活动专题

需求是运营给的,抢购活动核心就是要使用预约码,就是预先领取一个号码,等抢购那天凭此码来抢,没预约码的就哪凉快哪呆着哈。

UED设计活动专题页,设计花了一天就把设计搞弄出了。

前端与php负责切图,拉数据,领取预约码等,代码与调试各花了一天。

后端预约码领取数量,预约码查询,手机验证等都是用java处理。这代码都是以前写好的,我就测试了一下,还能用就给他们了。

终于在21号晚上上线。在公司待到9点,没发现啥事,就高高兴兴回家了,
突然在回家路上运营来电,就知道有事发生,
果然回家一看,老用户可以正常领取,新用户就领半天都不行,一猜是手机未绑定问题,
之前是看着前端同学测试的。到线上就没了,郁闷之极,第二天一早就陪他们改bug,却发现还有其他问题
1.答题错误就永远错误,是关闭弹窗校验问题。
2.用户完善手机号时又多请求一次,会提示此号码已被使用。
最后在上午终于改完,一切ok。只是关闭弹窗要刷新页面,因时间问题就没让他们改了。不影响领取。
其实看他们调试发现有以下几个问题:
1.由于是模版发布,前端同学有时候直接在编辑页改代码,代码没保存到就会丢失了
2.由于有缓存原因php同学与前端同学保存代码不一至,还好二人坐一起,可以商量弄 ,坐远了,改了就不知道谁覆盖了谁的代码了
3.看他们在用alert调试代码,要添alert代码,保存发布很费时间,而且不精准定位问题,其实firefox,chrome的debug功能还是比较强大的。

防高并发

应对高并发请求,首选nginx,能抗住每秒2万请求,嘿嘿,没写过nginx,
老大让我自己想办法,代码之前老大有写过的。我就照着他的代码,写了一个。
其实都简单,核心是有个计数器的东东。超过多少人就重定向到系统繁忙页了。
如果全都放进来,java是抗不住的。预计抢购当天有1万人。
在开发过程中又发现问题:
1. 请求java取活动时间时,在nginx有缓存,导致活动时间有延时现象。
2.活动专题页与抢购页的倒计时不同步,因为活动专题是php的,抢购页是java的 各自取时间不一样,最后统一取nginx服务器时间。

开始抢购

在26号上午12点08分大家开始抢购,此时流量直线上升,打开页面有些缓慢。
后台显示一单单的抢购成功幸运者,并付款成功。好吧可以开开心心的吃午饭了。
吃饭中微博却像突然一盆冷水泼来。搞的吃不下饭,网友在微博上大骂怎么预约码错误。
后来找了一个下午原因,从代码,缓存数据取出,日志分析都未找到真正正确的原因。
郁闷中度过一个下午。。。
遇到这事只能以后防范:
1.永远不要让用户知道哪错了。让他知道其实是系统太忙了就好或还在排队中。可以减少公关压力
2. 加多一些日志记录

end

log4j MDC 工作原理

缘起

前几天接到一个任务,要分析日志,看是谁在线上乱操作。非常郁闷的是在关键请求url操作功能上没有记录到userId。 虽然在InitMDCFilter时有记录userId。但是InitMDCFilter 加载顺序稍后于PageFilter,所以userId没有输出。 经老大提醒,本应在InitMDCFilter 里remove掉的,改在PageFilter 先取到userId,然后remove,伪代码如下 InitMDCFilter :

  try {
        MDC.put("userId", userId);

        chain.doFilter(request, response);

    } finally {

    }

PageFilter :

 try {
        chain.doFilter(request, response);

    } finally {
        log.info(requestUrl+MDC.get("userId"));
        MDC.remove("userId");
    }

一开始不明白神马原理,经看了MDC的源码就明白了

原理

1.先在log4j.xml的ConversionPattern配置 %X{userId},PatternParser会去解析
2.当请求过来时先经过PageFilter(因用户未登录也必须输出请求url,而如果InitMDCFilter先的话,用户未通过登录校验就不执行PageFilter,最后请求url数据都会没有)
3.再经过InitMDCFilter,先验证用户是否登录,登录后取出userId,通过 MDC存储userId,MDC会将数据放入ThreadLocalMap存储
4.由于运行时InitMDCFilter 与PageFilter 是同一个Thread的,所以他们可以共享ThreadLocalMap数据,所以PageFilter 可以在finally里取出userId
5.log4j通过MDCPatternConverter又从MDC里取出数据并打印日志
6.最后在finally里remove数据

PathMatchingResourcePatternResolver 找配置文件

在使用PathMatchingResourcePatternResolver 查找指定配置文件时遇到一个问题,就是有些目录下不会去找。

原因跟启动时 -classpath 有关,classpath没有加载要扫描的目录,如果使用maven,就是pom没有依赖到相关的项目

 ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

    try {
        Resource[] metaInfResources = resourcePatternResolver
                .getResources("classpath*:**/*.xml");
        for(Resource r : metaInfResources){
            System.out.println("URL:"+r.getDescription());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

GenerateAllSetter

介绍

GenerateAllSetter 是我在intellij idea开发的一个生成调用Set方法的插件,
在开发时有时候会遇到初始化domain时需要调用很多Set方法,
需要人工一个一个操作,非常的麻烦,所以开发了这个插件,提高效率。

插件安装

1.直接下载GenerateAllSetter.jar放到本地磁盘,也可下载源码自己打包
2.然后在intellij idea 插件安装,选install plugin from disk 安装重启即可使用

插件使用

在new domain时,需要初始化调用所有Set方法时,只需要将光标移动到类上,
然后按快捷键( Ctrl+Shit+G )或(alt+insert -input all set>,就会自动生成代码

插件开发 参见intellij idea development

HTTP Trace插件

HTTP Trace插件是google chrome 的插件,用于追踪页面上都有哪些http请求, 所以请求,http header,cookies等

使用场景:
1.监测页面上的所有http请求或参数 在看维品会的微信支付,一直看不清楚维品会的链接跳转,用此插件就可以跟踪到所有链接

2.查看http header
今天遇到联合登录过来先请求java是,然后再跳转到php交互时,产生的session不一至问题,
用http trace追踪也很容易发现

上线

今天blog终于上线了。

blog所涉及的开发:
语言:python
框架:django
数据库:mysql

感谢运维刘荣星同学提供域名,服务器等支持,