Category Archives: Architecture

Library dependency V.S. Remote API dependency in SOA

Pros of Library Dependency: Simplicity in terms of implementation. In java, all you need is Maven. There is no need for any RPC serialiser or RPC middleware.  Simplicity in terms of deployment. You will need less applications than the RPC approach. Each application requires investment of auto-deployment, monitoring, hardware resources, and load balancing in some […]

Layering in Java Webapps – My Final Version

What a good layering solution should do It must handle the following problems: 1. Dividing a system into layers based on modularization principles, such as single-direction dependency, limited entry of components and so on.  2. Compatible with modern dependency management tools such as Maven  3. Allowing for evolving into a distributed system in the future  […]

Tips about writing a scraper

Workflow Model:  Download All Pages Before Parsing Them Website scraping is a batch work. Basically there are two workflow models in this job.  One is: download page1 => parse page1 and save records of page1 =>  download page2 => parse page2 => …  .   The other is  download all the pages => parse and save […]

集群环境下慎用本地缓存

集群环境下慎用本地缓存。 用户1在机器A上看到100条记录,用户2在机器B上看到的却是90条记录。 你会说你的业务允许两边看到不一样。 是的,两个用户看到的不一样不要紧。 但是同一个用户看到不一样的话,用户体验会非常差,差到要骂人。 例子是:用户1在机器A上提交表单删除100条记录,服务端处理完毕后让浏览器跳转(Redirect after Submission),负载均衡将这个请求跳转到机器B上,机器B上的本地缓存没变,所以仍然是删除前的记录数。 用户1看到这个结果,脑子里只有一个想法:删除没起作用。 所以,集群环境下使用本地缓存,一定要保证同一个用户先后访问的是同一台机器。

基于比较的分页机制 V.S. 页码式分页

基于比较的分页机制中,输入是一个被比较值。 页码式分页机制中,输入则是页码。 用户体验 对于数据不断增长的功能,页码式分页机制在用户体验方面有个缺点:你翻到下一页时可能会看到刚刚已经看到过的记录。 以贴吧为例,你进到第一页时,你看到的是06,05,04这三条记录;翻到第二页时,本应看到的是03、02、01。 然而在你翻页之前,另一个用户插进了记录07记录; 这时再看第二页时,系统认为此时第一页是07、06、05,于是把第二页04、03、02返回给你,而你刚刚已经看了记录04. tps越高,这种现象就越严重。 而基于比较的分页机制就没有这个问题。第一页看到06, 05, 04; 翻到第二页时,客户端 “告诉系统我要比04更小的三条记录”, 不管这时有没有新增记录07,系统收到的指令都是“比04更小的三条记录”,所以总是返回03、02、01. 性能 如果要对分页查看列表的功能进行性能优化,一个常见的策略就是对前几页进行缓存。用缓存有一个问题:缓存的key是哪些? 对于页码式分页机制,缓存的key就是页码;要缓存前N页,只需缓存N个key对应的数据。 而对于比较式分页机制,缓存的key是什么? 它可能是你系统中的任何值,而且随着数据的增减,这个值可能原来是页尾,马上就又不是了。 要缓存多少个key?  只能把所有值都缓存一遍。除了首页由于被比较值固定为0可以缓存之外,其他页都无法缓存。 用户足迹追踪 比较式分页机制对用户足迹追踪不利。你很难根据访问记录(如access log),决定大部分用户会下翻多少页;而页码式分页机制就没这个问题。

开发A/B测试功能的注意事项

有一些注意事项: 1. 用户所见的一致性: 张三始终看到的是A版本,李四始终看到的是B版本,否则用户会很疑惑,甚至感到被玩弄感情。关于一致性还要考虑一些边界情况:     a. 一个匿名用户在同一台机器上操作多次,应该看到同一个版本     b. 一个匿名用户看到A版本以后,再注册,仍然应该看到A版本 2. 系统应该有一个后门,随心所欲地在A/B间互切,以方便在测试阶段进行测试。 3. 使用框架,尽量减少对业务代码的侵入性,要终止A/B测试时,可以轻松搞定。框架应该重点解决一个问题:封装一个接口,返回当前请求应该对应的版本号,业务执行代码自己不应该做这个判断; 这个接口的实现可以是框架内置的通用逻辑,也可以由使用者根据特定业务实现。 4. 一次分桶测试结束后,应该清理这次测试在业务代码中的残留点,否则随着测试越来越多,这些残留点会使代码的可读性越来越多。 部分参考了: http://www.slideshare.net/patio11/ab-testing-framework-design-3296257

影响业务逻辑的标签、徽章应该由开发人员创建

社区系统里的各种标签、徽章应该由谁创建,由谁来贴标签、颁发徽章? 贴标签、颁发徽章当然要由运营操作人员来做。 谁来创建呢?如果这个标签仅仅用来显示,而不会扭曲任何if/else逻辑,那可以由操作人员在后台界面上完成。 否则,就应该由开发人员创建,因为代码里要用它。如果还没创建好,怎么用它? 一般情况下,可以仅仅作为枚举类写死在代码里,连数据库表都不用建。

统计值在持久化前做一下校验:不能在值域之外

由于并发、程序bug或其他原因,你的统计值或多或少可能不那么准确。 如果说不准确可以勉强接受,超住值域之外就属于丢脸了。 如果你的页面上显示一个人发过的帖子数为-1 , 那就贻笑大方了。如果是0。即使不精确,也还说的过去。 所以,在持久化任何统计值之前,先把这个值正规化为值域的边界值(比如,小于0则置成0)。