svn批量处理

批量添加文件至svn

svn update | awk ‘{if($1 == “?”){print $2}}’ | xargs svn add

svn commit

 

批量解决 : Node remains in conflict

svn resolve –accept theirs-full .
svn update | awk ‘{if($1 == “Skipped”){print $2}}’ | xargs svn resolved
svn update
svn resolve –accept theirs-full .

nginx proxy造成大量wait timeout连接

nginx使用的是1.4.5,发现产生了大量wait timeout,网上搜索得知需要指定为http 1.1及keepalive可大量减少wait-timeout连接。

修改配置添加keepalive字段到upstream。

<span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<code class=""><span class="line">upstream backend_abc {
</span><span class="line">    server   192.168.1.34:8086 weight=1 max_fails=2 fail_timeout=10s;
</span><span class="line">    server   192.168.1.77:8086 weight=1 max_fails=2 fail_timeout=10s;
</span><span class="line">    keepalive 16;
</span><span class="line">}</span></code>

同时修改配置添加http1.1声明和header中connection重写。

<span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<code class=""><span class="line">server {
</span><span class="line">        listen       80;
</span><span class="line">        ....
</span><span class="line">  location / {
</span><span class="line">            proxy_pass         http://backend_abc;
</span><span class="line">            proxy_http_version 1.1;
</span><span class="line">            proxy_redirect     off;
</span><span class="line">            proxy_set_header Connection "";
</span><span class="line">            ....
</span><span class="line">  }
</span>
<span class="line">    }</span></code>

android隐藏标题栏与状态栏

requestWindowFeature(Window.FEATURE_NO_TITLE);    // 隐藏标题栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);  // 隐藏状态栏

上面两行注意要在setContent之前调用。

Required plug-in compatibility UUID not present in DVTPlugInCompatibilityUUIDs

上周五升级了xcode,结果打包时失败,提示错误:

2015-04-11 17:09:54.827 xcodebuild[49636:2989038] [MT] PluginLoading: Required plug-in compatibility UUID 9F75337B-21B4-4ADC-B558-F9CADF7073A7 for plug-in at path ‘~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Unity4XC.xcplugin’ not present in DVTPlugInCompatibilityUUIDs

今天看了下,应该是因为升级导致插件的uuid对应不上。

以下脚本修复这个问题。

XCODEUUID=`defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID`
for f in ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/*; do defaults write "$f/Contents/Info" DVTPlugInCompatibilityUUIDs -array-add $XCODEUUID; done

参考:

http://stackoverflow.com/questions/20732327/xcode-5-required-plug-in-not-present-in-dvtplugincompatibilityuuids

ipa如何确认是否为64位

打出的ipa包,实际是使用的zip格式。
在mac os下可以使用unzip直接进行解压
unzip Unity-iPhone4444.ipa
会在当前目录下生成Payload目录,
进入Payload目录
使用命令lipo来查看,通过ipa中的可执行文件放在     xiyouxiangmopian.app/xiyouxiangmopian
输出 arm64表示已经是64位包
localhost:Payload sanx$ lipo -info xiyouxiangmopian.app/xiyouxiangmopian
Architectures in the fat file: xiyouxiangmopian.app/xiyouxiangmopian are: armv7 arm64
localhost:Payload sanx$

dialog没有全屏

项目中使用了视频,视频上下都是黑边,所以设置backgroundcolor为黑色,但是最上面有一点一直没有被填充上(黄色部分),写测试发现是视频所在的dialog没有全屏。

最早怀疑是最上面的状态栏的问题,看高度正好和状态栏的高度相同。

但无论如何设置backgroundcolordrawable,padding,margin,layoutparam都无法解决问题,而且输出查看也没问题。

只能采取减少法了,不断删除相应的代码并观察,看看删除到哪里才不出现这个问题。

在删除时,突然发现在有段代码有:

		// this.getWindow().setLayout(screenWidth, screenHeight);

		mButton.setVisibility(View.INVISIBLE);
	}

看上面被注释掉那一行,这段代码在设置了视频了dialog后又重新了window的layout,难道问题出在这里?注释掉果然解决掉了问题。

 

java threading

一个老外哥们实现的non-blocking future,可是写法未免太反人类了点。

看来java处理这方面果真是弱项。

http://stackoverflow.com/questions/826212/java-executors-how-to-be-notified-without-blocking-when-a-task-completes

http://fasterjava.blogspot.de/2014/09/writing-non-blocking-executor.html

看要要转向vertx.io / skynet 比较好一些。

ssh连上断开的session

网络不好时,ssh远程连服务器经常断掉,如果原来启动一个带输出的程序,断线重连后,无法继续看下原来的输出。

http://www.gnu.org/software/screen/

screen可以实现断线后继续连上原来的session,当然,ssh后,先启动screen,断线重连后,使用 screen -r即可以继续原来的session.

mysql jdbc failover

因为项目中有多个cobar节点,现在只是连接的单一cobar节点,想修改为连接多个cobar节点,失败后,自动切换至其它节点。

原来看druid时,印象中有druid-ha,高高兴兴拿过来用,发现无法使用,再看源码,发现根本就没实现嘛。

在网上搜索了下,相关的资源也不是非常多。

好在需求很简单可以自已来造个轮子。

代码如下:

package cn.joylab.game.util;

import java.sql.Connection;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.datasource.AbstractDataSource;

public class HADataSource extends AbstractDataSource {

	private List<DataSource> targetDataSources;
	private int index = RandomUtils.nextInt(2);

	public List<DataSource> getTargetDataSources() {
		return targetDataSources;
	}

	public void setTargetDataSources(List<DataSource> targetDataSources) {
		this.targetDataSources = targetDataSources;
	}

	public Connection getConnection() {
		log.info("getConnection()");
		for (int m = 0; m < targetDataSources.size(); m++) {
			try {
				DataSource dataSource = targetDataSources.get(index);
				Connection conn = dataSource.getConnection();
				log.info("getConnenction success from index : " + index);
				return conn;
			} catch (Exception e) {
				index = (++index) % targetDataSources.size();
				log.error("ERROR", e);
			}
		}
		throw new RuntimeException("db connection error");
	}

	public Connection getConnection(String username, String password) {
		log.info("getConnection() with username and password");
		return null;
	}

	private static final Log log = LogFactory.getLog(HADataSource.class);
}

只是简单的进行下datasource的切换。

数据流加密

最近看了下数据流加密。

最初项目组采用了rc4加密,但双方密钥直接明文存储。被确解的可能性很大。

看了云风介绍了,使用dh进行rc4密钥交换,遂动手进行处理。

dh是非对称加密算法,用于交换密钥。

服务器使用java

客户端使用c#

采了几个坑:

1、java中pubkey使用X509格式存储,prikey使用PKCS8格式存储,如果要取到原始明文,需要使用:

public static Map<String, BigInteger> initKeyRaw() {
		try {
			KeyPairGenerator gen = KeyPairGenerator.getInstance("DH");
			gen.initialize(KEY_SIZE);

			KeyPair keyPair = gen.generateKeyPair();

			DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
			DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();

			Map<String, BigInteger> ret = Maps.newHashMap();
			ret.put("x", dhPrivateKey.getX());
			ret.put("y", dhPublicKey.getY());
			ret.put("p", dhPublicKey.getParams().getP());
			ret.put("g", dhPublicKey.getParams().getG());
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Map<String, BigInteger> initKeyRaw(BigInteger y, BigInteger p, BigInteger g) {
		try {
			KeySpec keySpec = new DHPublicKeySpec(y, p, g);
			KeyFactory keyFactory = KeyFactory.getInstance("DH");
			PublicKey pubKey = keyFactory.generatePublic(keySpec);
			DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams();

			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());
			keyPairGenerator.initialize(dhParamSpec);

			KeyPair keyPair = keyPairGenerator.generateKeyPair();

			DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
			DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
			Map<String, BigInteger> ret = Maps.newHashMap();
			ret.put("x", dhPrivateKey.getX());
			ret.put("y", dhPublicKey.getY());
			ret.put("p", dhPublicKey.getParams().getP());
			ret.put("g", dhPublicKey.getParams().getG());
			return ret;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

2、第二个坑

在网上找了一个c#版的dh源码,如果发现两边生成的key怎么都不对,最后定位到,java 中的biginteger是带符号位的。c#版中的biginteger是无符号位的,计算结果当然就不正确了。

我的解决方式是在java中转为biginterger前,添加“00”,这样避免了biginteger变为负数。