2015年的那些事

迟到的年终总结

那天一位老友问我怎么还没写2015年总结?

为什么要等我的总结?

他说他也准备写,想先看看我的…

我突然想到了学生时代的一句话:喂,你作业做好了借我抄一下。

 

其实,今年写这么晚主要是在等一个时间点,因为一些事只能在这个时候才方便说。

现在时间点已过,我就随便说说吧。不像往年,我今年就不列自己看了多少书学了多少东西了,那样太俗。

(๑•́ ₃ •̀๑) 啊。。。别揭穿我,其实真相是,我今年真的没看几本书…

API 蓝图

对 API 文档的幻想

你对 API 文档有哪些需求?写起来方便看起来舒服?

这两个应该是文档最基本的需求了。

其实,前后端配合开发的时候,还常常会有这样一种需求:

“你接口定义好了吗?定义好了的话能不能先帮我做一个 Mock Server 让我先跑起来?”

Alfred2 插件:Hasher

工具化思维

最近在做的项目,需要频繁地转换 timestamp 到人类可识别的日期时间文本。之前一直在用一个 Chrome 的插件,可以快速转换各种格式,但是每次都要切换到 Chrome 实在是太不方便了,每次都要浪费1-3秒。这对一个懒人来说,是无法接受的。所以决定开始造工具了!

然后最近正好又买了正版的 Alfred2,也学了一点点 Python,那用 Python 给 Alfred2 做一个插件就再合适不过了!

源码和下载地址:传送门

自定义 JDBC Driver 连接公司数据库

DataGrip

DataGrip

JetBrains 家最近发布了新的数据库管理工具:DataGrip

Mac 上其实一直没有好用的数据库管理工具。Sequel Pro 一天一崩溃;MySQL 官方的各种快捷键很奇怪,而且只支持 MySQL;其他的就更别说了,根本没到可用这个级别。

DataGrip 就不一样了,用惯了 Intellij IDEA 后会非常熟悉。

DataGrip 的大部分功能(基本是所有功能,目前还真没发现什么不一样的)其实在 Intellij IDEA 里都有,那为什么还要额外装一个呢?

好吧,其实我是买了 JetBrains 家所有产品的授权,所以对我来说都不需要额外付钱了。

所以其实无论你是用 Intellij IDEA、 PyCharm 还是别的 JetBrains 家产品,都可以找到同样的数据库管理功能。

利用 PhantomReference 替代 finalize

问题来源

之前的一篇文章讲了 利用 WeakReference 关闭守护线程 ,守护线程一旦发现守护的对象不在了,就把自己清理掉。

这次的问题更棘手一些,假如一个对象有一些资源需要被关闭,那怎么处理?

很多人会说,这个简单啊!用 Java 的finalize

但在 Java 中的finalize真的设计得不好,一不小心就会引发很多问题。

解决 MHA 切换后导致应用无可用连接的问题

问题来源

环境:MHA + MySQL + c3p0

最近在一次 MHA 切换的时候,发现应用中的 c3p0 老连接一直在等待,而新进来的请求全部被 c3p0 拒绝了。

然后又过了很长时间,老的连接断开,然后恢复了正常。整个过程极其诡异。

利用 CDN 解决百度爬虫被 Github Pages 拒绝的问题

百度爬虫被 Github Pages 拒绝

前两天在知乎看到一个问题:如何解决百度爬虫无法爬取搭建在Github上的个人博客的问题?

我一看,这不是和我的情况一模一样吗?

我赶紧上去看了看我网站的统计信息:

Netty 自动重连

自动重连

用 Netty 写 Client 和 Server 的时候必须要去处理自动重连。

Server 端启动时的错误,要去不断重试。

Client 端不仅要处理启动时的错误,还要处理中途断开连接。

“秒杀”问题的数据库和SQL设计

问题的来源

上篇文章介绍了 ETL 场景下的高性能最终一致性解决方案,这次的问题也是一个常见的问题。

最近发现很多人被类似秒杀这样的设计困扰,其实这类问题可以很方便地解决,先来说说这类问题的关键点是什么:

  1. 一定要高性能,不然还能叫秒杀吗?
  2. 要强一致性,库存只有100个,不能卖出去101个吧?但是库存10000实际只卖了9999是否允许呢?
  3. 既然这里说了是秒杀,那往往还会针对每个用户有购买数量的限制。

总结一下,还是那几个词:高性能强一致性!

下文的所有解决方案是在 Mysql InnoDB 下做的。因为用到了很多数据库特性。其他的数据库或其他的数据库引擎会有不同的表现,请注意。

高性能、最终一致性的数据同步方案

问题的来源

先描述一下问题:

两个系统的数据需要做数据同步,可以是数据库到数据库,也可以是数据库到内存。要求高性能(速度快),最终一致性(数据不能错)。

2014年总结

一年一篇

又到了一年一篇时间了,今年真的有很多话想要说,也经历了很多很多很多,这些事是我在2013年完全想不到的。

但是没想到,我还是做了!

Netty 长连接服务

推送服务

还记得一年半前,做的一个项目需要用到 Android 推送服务。和 iOS 不同,Android 生态中没有统一的推送服务。Google 虽然有 Google Cloud Messaging ,但是连国外都没统一,更别说国内了,直接被墙。

所以之前在 Android 上做推送大部分只能靠轮询。而我们之前在技术调研的时候,搜到了 jPush 的博客,上面介绍了一些他们的技术特点,他们主要做的其实就是移动网络下的长连接服务。单机 50W-100W 的连接的确是吓我一跳!后来我们也采用了他们的免费方案,因为是一个受众面很小的产品,所以他们的免费版够我们用了。一年多下来,运作稳定,非常不错!

时隔两年,换了部门后,竟然接到了一项任务,优化公司自己的长连接服务端。

责任链模式

Chain of Responsibility

在 面向对象程式设计里, 责任链模式是一种软件设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。

传送门:责任链模式

Java 中见到最多的对责任链模式的应用就是在Servlets Filters中了:

public class LogFilter implements Filter  {
   @Override
   public void  init(FilterConfig config) 
                         throws ServletException{ }

   @Override                      
   public void  doFilter(ServletRequest request, 
                 ServletResponse response,
                 FilterChain chain) 
                 throws java.io.IOException, ServletException {

      // do something
      
      chain.doFilter(request,response);
   }
}

利用 WeakReference 关闭守护线程

不要让 this 在构造期间逸出

《Java 并发编程实战》中有这么一段:

不要让this在构造期间逸出。

原因很简单,因为如果在构造期间创建了一个新线程并把this传递给新线程,this还没有准备完毕,新线程如果提前使用调用一些数据的话可能会有未知的错误。具体的错误和JVM的实现有关,可能大部分情况下没问题,但是一旦有了问题,你恐怕找都找不到。

参考:

小米手环评测

坑爹的咕咚手环

自从买了咕咚手环后一直对其他手环念念不忘…

因为咕咚的太难用了!罪证如下:

  • 待机时间只有4天
  • 固件从来不更新
  • 软件基本没更新过
  • 只支持iOS,Android手机明明也有蓝也4.0,可以连接但是同步失败
  • 材质感不好,略丑,搭扣很容易松
  • 不防水,不能带着洗澡

可惜别的手环太贵,直到小米手环到了…

Mac OS 中使用QQ域名邮箱

Google 被墙之后

Google 被彻底墙掉之后,最不方便的就是手机端的邮件、联系人和日历的同步了。

电脑上可以翻墙,手机上没买 VPN,也不想手机一直开着 VPN 啊…

寻思了一番后,发现国内目前做得比较好的也就只有QQ邮箱了,对应的功能全部有。

WordPress 迁移 Github Page + Jekyll

关于这次迁移

为什么迁移

博客写了5年,最烦的就是维护 WordPress 了。WordPress 的写作体验实在是太糟糕了,而且后台非常卡!

近几年 git 兴起,也衍生出了 Markdown 这样最适合程序员的写作方式。另外自己在一年内从 Windows 脑残粉变成了 *nux 脑残粉,更喜欢在 Bash 下干各种事情了。

所以趁阿里云过期之际,顺便把迁移这事做了。

恩,Github Page 是免费的!每个月立省 70!

为什么不迁移

Github Page + Jekyll 的方案很早就有了,我为什么到现在才迁移呢?

其实之前也考虑过,但是主要是遇到了如下难题:

  • 之前的文章是以 html 的形式存在数据库的,怎么做迁移?
  • 分类和标签怎么迁移?
  • 之前的静态资源怎么办?
  • 博客的 URL 会变吗?
  • 评论怎么办!

只是很久之前遇到的问题,今天回头看看发现,各个难点都有了很好的解决方案了。

所以这里给大家介绍一下~

Netgear3700v4 PK 小米路由器 mini

入手小米路由器 mini

小米路由器 699 版开放购买好久了,但是家里已经有了主路由,NAS 什么的也都搭建好了,没有必要再买一个。

这次 mini 版开售,终于买了一个,主要是想看看传说中的高性价神器到底怎么样!

 

参数对比

型号 价格 CPU 内存 无线 有线
Netgear 3700V4 499 Atheros AR9344 560 MHz 128MB 2.4GHz/5GHz 11a/b/g/n 1000M * 4
小米路由器 mini 129 MT7620A 580MHz 128MB 2.4GHz/5GHz 11a/b/g/n/ac 100M * 2

 

表格一列,一目了然。

论性价比,小米无敌,但是 mini 版的有线是硬伤!无线那么强大,有线竟然才 100M,应该还是处于成本的考虑吧。

但是实测下来怎么样呢?人家 TP 的参数也是很高的哦,实测才是硬道理!

电信光纤猫 HG8245C 破解

HG8245C

搬家后最痛苦的一件事就是,电信新版的光纤猫不能破解!所以不能从 NAT 改桥接让路由器直接拨号。

我也时常去网上搜搜破解教程,最近终于在淘宝找到了!最终花了60元找人远程搞定。

卖家人不错,我也帮忙推荐一下:http://item.taobao.com/item.htm?id=38921723002

git reset 在持续集成系统中的问题

持续集成

公司用上持续集成后开发效率大大提升,提交代码以后就会自动打包部署,分分钟见效!

所以自己在做东西的时候,也搭建了一套类似的环境。但最近却遇到了一个深坑。

 

reset and revert

git 中的resetrevert是两个非常有用的命令,它们的细节不是本文的重点,简单的总结一下:

  • reset可以让commit回退,就像从来没发生过一样。
  • revert可以自动生成一次完全相反的commit,以撤销之前的操作。

这次遇到的坑来自于reset,因为reset看似是一个时光机,但是有些情况下是无法抹去了。