安装配置 Supervisor
在线安装
通过
Setuptools
安装easy_install supervisor
Ubuntu 安装
sudo apt-get install supervisor
离线安装
- 从 PyPi 下载
supervisor
离线包 - 下载依赖项
- setuptools (latest) from http://pypi.python.org/pypi/setuptools.
- meld3 (latest) from http://www.plope.com/software/meld3/.
- 分别通过
python setup.py install
安装
注:根据不同的系统,可能需要 root 权限执行安装
在 travis 添加 ssh key
生成 SSH key
生成
1
ssh-keygen -t rsa -b 4096 -C "<your_email>" -f github_deploy_key -N ''
注: 这里使用
github_deploy_key
作为存储的名字
这会生成两个文件
公钥
github_deploy_key.pub
私钥
github_deploy_key
拷贝公钥到剪贴板
1
2# Copies the contents of the id_rsa.pub file to your clipboard
$ clip < ~/.ssh/github_deploy_key.pub如果是做为项目的部署公钥,需要添加到项目中,以 GitHub 为例,添加公钥的时候需要勾上
Allow Write Access
删除
github_deploy_key.pub
1
rm github_deploy_key.pub
安装 The Travis Client
首先确保已经安装好 Ruby (1.9.3+),官方推荐 2.0.0
执行
gem install travis -v 1.8.8 --no-rdoc --no-ri
安装 travis client检查安装是否正确
travis version
加密 SSH key
加密文件
1
travis encrypt-file github_deploy_key
加密后的文件为
github_deploy_key.enc
会输出类似的结果:
1
2
3
4
5
6
7
8
9
10
11encrypting github_deploy_key for <username>/<repository>
storing result as github_deploy_key.enc
storing secure env variables for decryption
openssl aes-256-cbc -K $encrypted_XXXXXXXXXXXX_key -iv $encrypted_XXXXXXXXXXXX_iv -in github_deploy_key.enc -out github_deploy_key -d
Pro Tip: You can add it automatically by running with --add.
Make sure to add github_deploy_key.enc to the git repository.
Make sure not to add github_deploy_key to the git repository.
Commit all changes to your .travis.yml.注: 如果是 GitHub 项目,建议先通过
travis login
登录,然后再通过travis encrypt-file github_deploy_key -add
加密,travis Client 会自动更新.traivs.yaml
并且在 travis 中自动添加变量encrypted_XXXXXXXXXXXX_key
和encrypted_XXXXXXXXXXXX_iv
删除
github_deploy_key
1
rm -f github_deploy_key
修改 .travis.yaml
在 before_install
添加如下内容:
1 | before_install: |
注: 步骤如下:通过 openssl 解密文件并输出到
~/.ssh/github_deploy_key
中;设定~/.ssh/github_deploy_key
文件权限并添加到ssh-agent
中
ssh_config
内容,主要是防止首次连接的时候,会弹出提示。如果有其他的地址,参考此设置即可。
1 | Host github.com |
至此,就成功在 travis 中添加了 SSH 密钥且能建立链接。可用于且不限于:
- 推送 CI 编译后的文件 / 结果
- 免费构建私有项目(这个可能会违反 TOS,不建议…)
- etc….
参考
- Connecting to GitHub with SSH
- Encrypting Files
—EOF—
通过 travis 自动部署 Hexo
准备工作
生成 GitHub 的 Personal access tokens,需要有 repo 相关权限
安装 Git deployer plugin for Hexo
1
npm install hexo-deployer-git --save
配置
配置 Hexo
在 Hexo 的
_config.yml
中添加 Hexo 编译好后文件的 git 地址,如果需要同时提交到多个不同地址,可以添加多个。1
2
3
4
5
6
7
8# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: https://__GITHUB_TOKEN__@github.com/{user_name}/{git_repo}
branch: master
name: gythialy
email: gythialy@users.noreply.github.com注:
https://__GITHUB_TOKEN__@github.com/{user_name}/{git_repo}
示例为https://__GITHUB_TOKEN__@github.com/gythialy/gythialy.github.io.git
配置 travis
在 Hexo 根目录添加
.travis.yml
,内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27language: node_js
node_js:
- "7"
branches:
only:
- raw
before_install:
- npm install -g hexo-cli
- npm install -g gulp
install:
- npm install
before_script:
- git config --global user.name 'gythialy'
- git config --global user.email 'gythialy@users.noreply.github.com'
- sed -i "s/__GITHUB_TOKEN__/${__GITHUB_TOKEN__}/" _config.yml
# use custom theme config
- git clone --branch v5.1.2 --depth=10 https://github.com/iissnan/hexo-theme-next.git themes/next
- git checkout -b v5.1.2
- cp next_config.yml ./themes/next/_config.yml
script:
- hexo generate && gulp && hexo deploy注: 因为源文件和生成的文件共用了 git repo,所以需要指定只编译 源文件分支(
raw
),master
作为编译好的文件存放路径。配置 travis 环境变量
在 travis 网页中添加变量
__GITHUB_TOKEN
__值为前面生成的 GitHub Personal access tokens
—EOF—
Java 通过 JNA 调用 C/C++ 接口
缘起
项目中调用了第三方一个 Matlab 实现的数据清洗和机组状态评价的算法,但是对方不会除 Matlab 外的其他语言,最后只用 Matlab 生成了一个 dll/lib 文件。由于对方提供的接口质量真心不好,而且对方也无力修改。最终方案只好由我方在其基础上用 C++ 重新包装一下。在给我方 Client 调用时,需要把从多数据源查询数据的细节封装掉,最终就形成了 Java Client-> Java Interface->C++ Interface->Matlab/C++ Interface (第三方) 这样一个诡异的调用链。
因只是 Java 单向调用 C++ 接口,故通过 [JNA][jna] 实现。主要设计到 JNA 的结构体封装,指针声明及取值,结构体指针定义及取值。
实现
C++ 的封装接口逻辑非常简单,根据业务提供数据清洗和机组评价的两个接口。
由于 Matlab 导出的 dll 效率是真心差,尤其时加载的时候,各种抛异常,每次加载 dll 大约需耗时 20~30s。所以不能每次加载,故提供 init/terminator
实现按需加载及停用。
C/C++ 头文件定义
1 | #ifndef __CALCULATOR_API_H__ |
Java 接口定义
CalculatorApi
CalculatorApi
提供与 C++ 头文件中声明一致的函数定义,继承Library
1 | import com.sun.jna.Library; |
FactorResultWrapper
作为 C++ 中 结构体
FactorResult
的封装类,需要继承Structure
,原始state
定义为float *
,通过Pointer
与其对应。必须要实现getFieldOrder
, 其中字段的顺序必须和 C++ 中保持一致,且所有相关字段必须要设成Public
。使用的时候,用的引用传递,所以必须要实现Structure.ByReference
接口。具体代码实现如下:
1 | import com.sun.jna.Pointer; |
FusionResultWrapper
作为 C++ 中 结构体
FusionResult
的封装类,定义同上。
1 |
|
ImproveInputWrapper
作为 C++ 中 结构体
ImproveInput
的封装类,就是基本类型映射。
1 | import com.sun.jna.Structure; |
ImproveResultWrapper
作为 C++ 中 结构体
ImproveResult
的封装类
1 | import com.sun.jna.Pointer; |
ReviewResult
作为 C++ 中 结构体
ReviewResult
的封装类,此处包含多个结构体指针,需要通过ByReference
来声明,且需要分配内存。比如TransformerWrapper.ByReference indexScore
,需要通过toArray
分配内存
1 | import com.sun.jna.Memory; |
TransformerWrapper
作为 C++ 中 结构体
Transformer
的封装类
1 | import com.sun.jna.Structure; |
CalculatorImpl
Java 接口的实现类,首先需要从 Jar 中解压 dll 到指定目录,然后通过此目录加载 dll。依赖关系为 Java 接口通过 JNA 加载
calculator.dll
,而calculator.dll
依赖pingjia.dll
和另外一个 dll。三个 dll 必须在同一目录下, JNA 只需要加载
calculator.dll
。因为此处只是在 WIN32 平台执行,所以加载时,通过Native.loadLibrary
加载的时候,在文件名前加了/
,否则 JNA 会在文件前增加平台相关的 perfix 导致加载失败。
1 | public class CalculatorImpl implements Calculator { |
使用
improveData
数据清洗,需要根据 Java Wrapper 的接口,组织数据,内存都在 Java 端分配,由 Java 端负责回收。Pointer
的内存分配,通过new Memory(size)
来分配。
1 | private TwoTuple<String, CalculationResult> improveData(String label, List<TwoTuple<String, Float>> values) |
reviewTransformer
机组状态评价,获取float *
的数据时候的,需要通过getFloatArray
获取数据。
1 | private TransformerResult reviewTransformer(Map<String, Float> values) throws CalculatorException { |
小结
- 优点
- Java 端不需要编写 C/C++ 代码
- 缺点
- 需要编写与 C/C++ 对应的结构体映射,碰到复杂的结构体工作量不小
- 结构体指针 / 数据通过
toArray
获取数据时,效率较低,尤其时数据量比较大的时候 - 如果时 C/C++ 端分配的内存,Java 端管理不了,如果 C/C++ 不提供显式回收接口,会导致内存泄露
- 代码不规范,破坏了 OO 封装性,比如 field 必须要 Public
- 需要实现
Structure.ByReference
接口,这些明显都可以通过注解来解决
[jna]:https://github.com/java-native-access/jna “Java Native Access”
—EOF—
GPG 导入导出 Key
在多台电脑上操作的时候经常会涉及到 GPG 公钥 / 私钥的导入导出,比方说 GitHub 支持 GPG 加密 Commit,在多台电脑上使用相同的 Key 可以省去很多配置工作。
列出本地的所有 Key
执行 gpg --list-keys
列出本地所有的密钥
输出结果类似
1 | $ gpg --list-keys /home/$USER/.gnupg/pubring.gpg |
导出
根据 375A500B
导出相应的公钥和私钥
1 | gpg --output mygpgkey_pub.gpg --armor --export 375A500B |
导入
导入刚导入的文件
1 | gpg --import ~/mygpgkey_pub.gpg |
删除密码
1 | gpg --edit-key 375A500B |
如果提示
Sorry, no terminal at all requested - can't get input
的话,需要 把~/.gnupg/gpg.conf
中的no-tty
注释掉
—EOF—
babun 配置
介绍
babun 号称是开箱即用的,本质是上就是 cygwin 加上了一些预设的配置。特性如下:
- Pre-configured Cygwin with a lot of addons
- Silent command-line installer, no admin rights required
- pact - advanced package manager (like apt-get or yum)
- xTerm-256 compatible console
- HTTP(s) proxying support
- Plugin-oriented architecture
- Pre-configured git and shell
- Integrated oh-my-zsh
- Auto update feature
- “Open Babun Here” context menu entry
安装
下载安装包解压缩到任意目录后,运行 install.bat
。也可以使用 /t %target_folder%
指定安装目录。
配置
既然是开箱即用,对大多数人来说当然不需要太多配置,一般需要以下两个命令:
babun check
用于判断环境是否正确babun update
用于判断是否有新的更新包
包管理
babun 自带了叫做 pact
的包管理,修改自 apt-cyg
, 但比较弱,用法如下:
1 | { ~ } » pact --help |
和 Windows 共享配置
- 添加环境变量
HOME
,值为 Windows 的用户目录C:\Users\%USERNAME%
- 启动 babun,执行
babun install
,重启 babun
% USERNAME% 不能包含空格。如果用户名已经有空格,参考这里解决。
代理设置
只需要取消 .babunrc
中的注释 (%USERPROFILE%\.babunrc
)
1 | # Uncomment this lines to set up your proxy |
镜像
修改 ~/.pact/pact.repo
中的 PACT_REPO
字段
1 | #PACT_REPO=http://mirrors.kernel.org/sourceware/cygwin/ |
常用开发环境配置
Python
babun 自带的 Python2 并没有安装 pip,需要手动安装
1 | pact install python-setuptools python-ming |
Ruby
执行 pact install ruby
如果
ruby -v
不能返回版本,执行update.bat
更新 cygwin 的版本。via Issue #483
FAQ
compdef: unknown command or service: git
1
2$ compinit
$ cp .zcompdump .zcompdump-$HOSTNAME-$ZSH_VERSION删除右键中的
Open Babun here
执行babun shell-here remove
与 ConEmu 集成
%userprofile%\.babun\cygwin\bin\mintty.exe /bin/env CHERE_INVOKING=1 /bin/zsh.exe
X64
官方对于 64 位的解释。懒人也可以直接使用这个 PR 编译的分发包。有兴趣的也可以通过我合并的 x64 分支 自行构建。
总结
总的来说,babun 比 MSYS2 慢,包也不多,稳定性 / 兼容性貌似好一点。
最终配置效果:
—EOF—
Jetty 配置 Log4J
缘起
我们一台很老的装置中用了 Jetty v7.1.6,由于种种原因,不能升级新版本。某次由于一个 bug 导致一直写日志,最后把硬盘给写爆了,所以用 Log4J 记录日志,方便控制日志大小等。
注:在 Jetty 最新的版本中,配置 Log4J 并不需要如此。
配置
下载 Log4J
- log4j-1.2.17.jar
- slf4j-api-1.7.9.jar
- slf4j-log4j12-1.7.9.jar
复制 jar 包到 Jetty 目录中
lib/ext
文件夹中1
2
3
4-rwxr-xr-x 1 root root 0 Jul 16 2010 .donotdelete
-rw-r--r-- 1 root root 489884 Nov 19 13:06 log4j-1.2.17.jar
-rw-r--r-- 1 root root 32121 Nov 19 13:09 slf4j-api-1.7.9.jar
-rw-r--r-- 1 root root 8867 Nov 19 16:55 slf4j-log4j12-1.7.9.jar在 Jetty 目录中 resources 文件夹中新建
log4j.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14# Basic Log4j Configuration with STDOUT and File logging
log4j.rootLogger=DEBUG, filer
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.filer=org.apache.log4j.RollingFileAppender
log4j.appender.filer.layout=org.apache.log4j.PatternLayout
log4j.appender.filer.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.filer.File=${jetty.home}/logs/jetty.log
log4j.appender.filer.MaxFileSize=1MB
log4j.appender.filer.MaxBackupIndex=20为了测试日志,配置设置的日志打印级别为 DEBUG,单个文件大小为 1M,实际使用中根据具体使用场景调整。
修改
start.ini
,OPTIONS 中ext
必须放在resources
前面1
2
3
4
5
6
7
8#===========================================================
# Start classpath OPTIONS.
# These control what classes are on the classpath
# for a full listing do
# java -jar start.jar --list-options
#-----------------------------------------------------------
OPTIONS=Server,jsp,jmx,websocket,ext,resources
#-----------------------------------------------------------注:如需手动设置 JVM 内存配置,需要添加
--exec
。这样就会有一个 java 进程常在。创建启动脚本,原理很简单,就是设置
JAVA_HOME
和JETTY_HOME
两个环境变量,然后调用 Jetty 自身的脚本。如果已经设置全局的环境变量,此步可省略1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#!/bin/sh
export JAVA_HOME=/usr/java/jdk
export JETTY_HOME=/home/data/jetty
cd $JETTY_HOME/bin
pwd
case "$1" in
start)
./jetty.sh start
;;
stop)
./jetty.sh stop
;;
restart)
./jetty.sh restart
;;
*)
echo "Usage: $0 $1 {start|stop|restart}"
;;
esac
exit 0脚本中
JAVA_HOME
和JETTY_HOME
是必须的。
效果
1 | -rw-r--r-- 1 root root 27995 Nov 30 14:51 2015_11_27.stderrout.log |
start.log 是 start.jar 创建的,会根据
etc/jetty-logging.xml
中配置决定是否从定向内容。
—EOF—