存档

‘工作’ 分类的存档

Java初始化中的clinit和init

2015年7月13日 没有评论

单纯理解Java的初始化,可以认为有两步,静态初始化的类构造器clinit和实例化的实例构造器init的初始化。
clinit发生在首次访问期静态数据或方法时,再或者是首次new的时候,在init之前。

什么时候有clinit?
《深入理解Java虚拟机》书中给出了大致的答案:

<clinit>()方法是由编译器自动收集类中的所有变更的赋值动作和静态语句块(static{}块)中的语句产生的

这句话总结的非常到位,但下面补的这一刀很容易把人带到沟里去,大意:

如果一个类中没有静态语句块,也没有对变量的赋值操作,可以不为这个类生成<clinit>()方法。

直接的理解是,不出现下面这两种代码,就不需要clinit方法;相反的,出现了,就需要。

//1.静态变量或静态常量
private static Xxx xxx = ....;
private static final Yyy yyy = ...;

//2.静态代码块
static{
Xxx.xxx();
Yyy.yyy();
}

实际上并不是这样的。我下面具体描述一下。
更多内容…

分类: 工作 标签: , , , ,

MySQL崩溃之utf8mb4的like非左匹配

2015年7月8日 没有评论

线上数据库崩溃,怀疑是utf8mb4编码导致的,目前已经重现,并找到具体的解决办法。

原因:
当支持utf8mb4的字段中出现emoji表情时,用like ‘%xx%’方式全搜索时,崩溃。
应该是MySQL的bug,怀疑是因为emoji的编码长度是4,而utf8_unicode_ci是3,MySQL的like非左匹配操作时,碰到占4字节的utf8mb4时出现问题(猜测)。

解决办法:
用instr函数取代like。不崩溃且效率高。instr(‘abcd’,’ab’)值为1,instr(‘abcd’,’ca’)值为0。即大于0为命中。

总结:在like左匹配的时候,用原生like靠谱。如果是两边匹配的时候,like支持复杂语法,所以效率较低。普通的%xx%类型的搜索,直接instr即可搞定。
另外:instr的大小写匹配跟like一样,默认是大小写不敏感的。

以下是完整的异常信息。
更多内容…

分类: 工作 标签: , , , ,

StartSSL证书使用相关问题

2015年6月9日 没有评论

最近申请了startssl的多个https证书,碰到一系列问题,逐个备忘一下。

1、nginx对同一个IP上多个域名证书的支持,下面的:TLS SNI support enabled。

#./nginx -V
nginx version: nginx/1.x.x
built by gcc 4.x.x 201xxxxx (Red Hat 4.x.x-x) (GCC) 
TLS SNI support enabled

如果不支持,需要重新编译openssl及nginx。

2、wget认证不过及firefox认证失败的问题。

ERROR: cannot verify www.xxxx.com's certificate, issued by `/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Class 1 Primary Intermediate Server CA':
  Unable to locally verify the issuer's authority.

某些浏览器或wget等工具没有内置StartCom Class 1 Primary Intermediate Server CA的证书为中级认证机构,认证链不完整,所以认证失败。
base64编码的cer,只需要把它的public的cer文件放到自己站点的public的cer下面即可。网上有人直接>>操作,导致中间没有换行,证书不认了,加个换行就对了。
加上它以后,它是被StartCom的根认证机构认证的,论证链就完整了。

3、apcache的Java的DefaultHttpClient,碰到nginx上配置多个证书时,访问其它域名的时候会出错。

javax.net.ssl.SSLException: hostname in certificate didn't match: <test.api.xxx.com> != <www.xxx.com> OR <xxx.com> OR <www.xxx.com>
        at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:228)
        at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
        at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149)
        at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130)
        at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
        at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
        at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
        at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:641)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)

跟了一下代码,AbstractVerifier.verify中得到的确实是默认的www.xxx.com的证书链,第一个是当前站点,第二个是问题2中加的中级证机构的public证书。
再往下没跟动,怀疑httpclient是用ip得到的证书,也就意味着它不支持同一个IP多个域名证书。解决方案就是实现X509HostnameVerifier以取消域名的验证。

 final X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {

            @Override
            public boolean verify(String host, SSLSession ssl) {
                return true;
            }

            @Override
            public void verify(String host, SSLSocket ssl) throws IOException {//实际上只会调用这个。
            }

            @Override
            public void verify(String host, X509Certificate cert) throws SSLException {
            }

            @Override
            public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
            }
        };
final SSLSocketFactory ssf = new SSLSocketFactory(ctx, hostnameVerifier);

Eclipse的Workspace体积暴涨问题备忘

2015年6月2日 没有评论

如题,发现Workspace的.metadata目录暴涨,备份的时候略吃力。
找了一下,发现是maven的插件导致的,清理一下就可以了:.metadata/.plugins/org.maven.ide.eclipse/nexus

分类: 工作 标签: ,

VPN搭建入门步骤备忘

2015年6月2日 没有评论

前几天让强子搭建VPN穿墙,很快搞定了,简单记录备忘之,以下是强子的原文转贴:

本次实验使用的centos 6.3 64bit。

一、安装之前检查系统兼容性。检查内核MPPE补丁,确定内核是否支持mppe:

modprobe ppp-compress-18 && echo ok

如果显示ok,表示内核已经具备了mppe支持。

二、安装VPN需要安装三个组件ppp、pptp、pptpd。本机yum命令有问题,只能通过wget方式进行。
可以到http://pkgs.org/search/pptpd?type=name这个网站上进行查找相应的安装包:
1.下载:

wget http://mirror.centos.org/centos/6/os/x86_64/Packages/ppp-2.4.5-5.el6.x86_64.rpm
wget http://mirror.centos.org/centos/6/os/x86_64/Packages/pptp-1.7.2-8.1.el6.x86_64.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/pptpd-1.4.0-3.el6.x86_64.rpm

2.安装:

rpm -ivh ppp-2.4.5-5.el6.x86_64.rpm
rpm -ivh pptp-1.7.2-8.1.el6.x86_64.rpm
rpm -ivh pptpd-1.4.0-3.el6.x86_64.rpm

三、以上把需要的三个组件都已经安装完毕,我们接下来进行配置。
1.pptpd的配置文件在/etc/pptpd.conf。
(1)在这个文件中需要把logwtmp注释掉:

#logwtmp

(2)然后配置本机的内网IP地址,以及客户端拨号进来后所要分配的IP地址:

localip 192.168.0.1
remoteip 192.168.0.201-250

2.启用ms-dns。路径在/etc/ppp/options.pptpd。
该DNS可以填写公共的DNS服务器,也可以是你自己配置的。一般使用谷歌公网DNS:

ms-dns 8.8.8.8

3.下面开始配置VPN访问的用户名、密码以及分配的IP地址。路径在/etc/ppp/chap-secrets。

user pptpd pwd *

4.开启防火墙的IP转发功能,路径在/etc/sysctl.conf。
(1)把net.ipv4.ip_forward赋值为1:

net.ipv4.ip_forward = 1

(2)保存并退出,使用sysctl –p命令使刚刚的配置生效。

sysctl -p

5.在防火墙中添加规则允许NAT转换。命令如下:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

6.现在开始启动pptpd服务。

service iptables start
service pptpd start

7.将服务配置为开机自动启动

chkconfig pptpd on
chkconfig iptables on

四、客户端连接。
在VPN服务器上查看多了一张网卡,而且也可以看到VPN客户端获取到的IP地址:

ifconfig

五、pptpd服务相关命令。

#重启:
service pptpd restart
#关闭:
service pptpd stop
#开启:
service pptpd start
分类: 工作 标签: , ,

Centos通过某台服务器中继上网

2015年5月28日 没有评论

转自贝贝的blog,略有补充,贝贝的原贴地址:http://www.thinkingquest.net/articles/449.html

有两个补充之处:
1、GATEWAY配置
Centos的GATEWAY配置不仅在ifcfg-eth0中,也可能在/etc/sysconfig/network中。ifcfg-eth0中对单个网卡有效,network配置的是全局,作用范围不同。
原理都是改GATEWAY。

2、转发配置:
修改/proc/sys/net/ipv4/ip_forward是临时性的,是内核的当前运行状态,永久的改动位于:
/etc/sysctl.conf的

net.ipv4.ip_forward = 1

改完后执行以下命令生效

#sysctl -p

生效后,/proc/sys/net/ipv4/ip_forward会自动变为/etc/sysctl.conf中net.ipv4.ip_forward的值。

下面附上贝贝的原文(我这访问只能绑host访问贝贝的blog,原文转过来更方便)。
--------我是分隔线,以下是引用的全文----------

几个vps(虚拟主机),只有一个拥有公网ip地址,所有的vps都拥有内网ip地址。其它的vps需要通过拥有公网ip的这个vps进行公网访问,以方便yum安装软件等需求。

在没有公网ip的vps上需要进行的设置:

/etc/sysconfig/network-scripts/ifcfg-eth0 文件中: GATEWAY=10.x.x.x

service network restart

到此完成。

接下来是拥有公网ip的那台vps上进行设置:

echo “1” > /proc/sys/net/ipv4/ip_forward

注意,这条命令是临时开启系统的转发功能,系统重启后会恢复为默认设置。 可以通过在/etc/rc.d/rc.local中加入上述命令,使之在系统启动时被执行。

打开iptables的nat功能:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

到此设置完成。

其它vps应该可以访问公网了。

分类: 工作 标签: , , ,