0%

默认情况下,git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可。如果要一次推送所有本地新增的标签上去,可以使用 - -tags 选项,运行git push origin - -tags

debian官方源里的shadowsocks最近用不了了。/var/log/shadowsocks.log里出现错误提示:

1
ERROR M2Crypto is required to use aes-256-cfb, please run apt-get install python-m2crypto

但是实际上python-m2crypto已经安装了,重新安装也不行。那就换个客户端shadowsocks-qt5试试。

安装依赖

1
$ sudo apt-get install qt5-qmake qtbase5-dev libqrencode-dev libappindicator-dev libzbar-dev libbotan1.10-dev

安装libQtShadowsocks
shadowsocks-qt5依赖于libQtShadowsocks,所以先安装libQtShadowsocks。

下载或clone libQtShadowsocks,项目根目录下执行:

1
$ dpkg-buildpackage -uc -us -b

在上一级目录中生成三个deb包:

1
2
3
libqtshadowsocks_1.8.0-1_amd64.deb 
libqtshadowsocks-dev_1.8.0-1_amd64.deb
shadowsocks-libqtshadowsocks_1.8.0-1_amd64.deb

安装前两个即可

1
2
$ sudo dpkg -i libqtshadowsocks_1.8.0-1_amd64.deb 
$ sudo dpkg -i libqtshadowsocks-dev_1.8.0-1_amd64.deb

安装shadowsocks-qt5
下载或clone shadowsocks-qt5,项目根目录下执行:

1
$ dpkg-buildpackage -uc -us -b

在上一级目录中生成:

1
shadowsocks-qt5_2.6.0-1_amd64.deb

安装deb包

1
$ sudo dpkg -i shadowsocks-qt5_2.6.0-1_amd64.deb

安装完成,配置见Shadowsocks科学上网

References:
[1]shadowsocks-qt5
[2]libQtShadowsocks
===
[erq]

提供gradle访问ssh执行命令、传输文件的功能。

安装
构建脚本中添加:

1
2
3
plugins {
id 'org.hidetake.ssh' version '1.1.4'
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
remotes {
webServer {
host = '192.168.1.101'
port = 2022
user = 'jenkins'
identity = file('id_rsa')
}
}

task deploy << {
ssh.run {
session(remotes.webServer) {
put from: 'example.war', into: '/webapps'
execute 'sudo service tomcat restart'
}
}
}

可以使用此插件通过ssh自动部署应用程序。

tomcat热部署会持续的泄露PermGen内存,因此还是常规的部署更靠谱,不过应用程序会暂时中断。

References:
[1]gradle-ssh-plugin
[2]Deploy your App from Gradle

===
[erq]

gradle调用gulp任务的插件。

安装

build文件中添加如下行:

1
2
3
plugins {
id "com.moowork.gulp" version "0.11"
}

调用gulp任务

插件将gulp task_name包装成gulp_task_name的方式从gradle调用。

可以从命令行上调用:

1
$ gradle gulp_task_name

这实际上会调用gulp task_name

更重要的,可以在构建文件中把gulp任务作为依赖:

1
2
// runs "gulp build" as part of your gradle build
build.dependsOn gulp_build

References:
[1]gradle-gulp-plugin

===
[erq]

集群信息

集群的名字叫fooCluser,总共有两个节点在同一个数据中心。每个节点位于不同的机架。
数据中心的名字叫DC1,两个机架的名字分别为RAC1和RAC2。
两个节点的IP分别为192.168.0.100和192.168.0.101。
因为只有两个节点,两个节点都作为种子节点。
注意:要保证所有的节点安装相同版本的Cassandra

操作步骤

  1. 停止节点
    debian包系统安装的cassandra,安装完成后处于运行状态,而且有默认的集群Test Cluster。
    停止所有的集群节点
    1
    $ sudo service cassandra stop
  2. 清除数据
    清除默认的集群(Test Cluster)信息
    1
    $ sudo rm -rf /var/lib/cassandra/data/system/*
  3. 修改cassandra.yaml配置
    核心的参数设置如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cluster_name: 'fooCluster'
    seed_provider:
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
    - seeds: "192.168.0.100,192.168.0.101"

    listen_address: 192.168.0.100
    endpoint_snitch: GossipingPropertyFileSnitch
    auto_bootstrap: false

不同的节点listen_address是不同的。如果需要开启thrift rpc server,还需设置rpc相关参数,对于当前版本的cassandra,rpc并不是必须的,只使用cql是可行的。

当初始化一个没有数据的新集群时,要设置auto_bootstrap参数为false。auto_bootstrap参数在cassandra.yaml中是没有的,其默认值为true,需要手动添加。种子节点是不需要bootstrap的,只有向集群中添加新的节点时,新加入的节点启动时需要bootstrap。
4. 机架感应配置
因为使用了GossipingPropertyFileSnitch,所以对应的数据中心、机架配置文件为cassandra-rackdc.properties
对于192.168.0.100节点,此文件内容设置为:

1
2
dc = DC1
rack= RAC1

而对于192.168.0.101节点,则设置为:

1
2
dc = DC1
rack= RAC2

注意:cassandra集群内的多个节点是可以放置于同一个机架内的,只不过cassandra认为,同一个机架内的节点容易一起失败,所以要尽量将数据分布到不同机架内的节点上。
5. 启动节点
先启动种子节点,每次启动一个,顺序启动所有种子节点后,再顺序启动其他节点。

1
$ sudo service cassandra start
  1. 查看集群状态
    1
    2
    $ nodetool status
    $ nodetool describecluster

References:
[1]Initializing a multiple node cluster (single data center)

===
[erq]

可以为现有集群添加一个新的数据中心,要求新添加数据中心的所有节点,要安装与原集群节点相同的cassandra版本。

操作步骤:

  1. 使用NetworkTopologyStrategy
    系统keyspace并没有使用NetworkTopologyStrategy策略,用户的keyspace如果要使用多数据中心就要使用NetworkTopologyStrategy策略。
  2. 停止节点
    debian包系统安装的cassandra,安装完成后处于运行状态,而且有默认的集群Test Cluster,因为需要逐一停止新数据中心节点,并清除默认安装的信息:
    1
    2
    $ sudo service cassandra stop
    $ sudo rm -rf /var/lib/cassandra/*
  3. 配置cassandra.yaml
    新数据中心节点cassandra.yaml文件中添加auto_bootstrap: false。auto_bootstrap默认是true,并且没有在cassandra.yaml文件中列出来。设置其他参数,比如seeds和endpoint_snitch,匹配原有集群的配置。num_tokens参数可以设置与原集群一致,但不要设置initial_token参数。
  4. 编辑相关配置文件
    GossipingPropertyFileSnitch使用的配置文件cassandra-rackdc.properties中添加新数据中心和机架。
  5. 客户端配置
    如果使用DataStax驱动,负载均衡策略设置为DCAwareRoundRobinPolicy,其他驱动做相应修改,以使客户端与新的集群相适应。
    如果原来使用一致性级别QUORUM,那么现在重新审视一下,是否LOCAL_QUORUM或者EACH_QUORUM一致性级别更适合现在的多数据中心集群。
  6. 新节点启动cassandra
  7. 新节点数据同步
    当集群中的所有节点都正常运行之后,修改keyspace的属性以便将数据分布到新的数据中心,比如:
    1
    2
    3
    cqlsh> ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1':2,'DC2':1};
    cqlsh> ALTER KEYSPACE system_traces WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1':2,'DC2':1};
    cqlsh> ALTER KEYSPACE system_distributed WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1':2,'DC2':1};
    在原数据中心或新数中心的任意节点上执行皆可。

然后新添加数据中心的每一个节点上运行nodetool rebuild,并指定原数据中心的名字:

1
$ nodetool rebuild -- name_of_existing_data_center

多个节点可以同时运行此命令。

  1. 还原auto_bootstrap参数
    新添数据中心节点的配置文件cassandra.yaml去掉auto_bootstrap参数或者将其值设置为true。如果新添加的节点是种子节点,则此参数应设置为false,种子节点不需要bootstrap。

References:
[1]Adding a data center to a cluster
[2]Using multiple network interfaces
[3]Apache Cassandra Deployed on Private and Public Networks
[4]Adding nodes to an existing cluster

===
[erq]

debian从官方源安装cassandra后,集群其实已经建立起来了,默认的集群名字为Test Cluster
直接更改/etc/cassandra/cassandra.yaml文件中的cluster_name,然后重新启动cassandra是行不通的。
有如下类似错误提示:

1
2
ERROR \[main\] 2015-11-06 22:44:41,853 CassandraDaemon.java:635 - Fatal exception during initialization
org.apache.cassandra.exceptions.ConfigurationException: Saved cluster name Test Cluster != configured name imageCluster

这是因为集群的名字存储在系统表中,当与配置文件中的集群名字不同时,就会出现以上错误。二者必须要一致才可以

1
2
3
cqlsh> UPDATE system.local SET cluster_name = 'test' where key='local';
# flush the sstables to persist the update.
bash $ ./nodetool flush

修改完后还要flush一下节点。如果更改集群的名字,集群中所有的节点要逐一这样改过才行。

最好在集群初始化之初规划好集群的名字,不要随意更改集群名字。

References:
[1]Saved cluster name Test Cluster != configured name
[2]Cassandra says “ClusterName mismatch: oldClusterName != newClusterName” and refuses to start
[3]Troubleshooting cassandra: Saved cluster name XXXX != configured name YYYY

===
[erq]

debian使用apache源安装完成的cassandra节点,默认数据存储在/var/lib/cassandra/data目录下。

为了优化性能,可能将data与commitlog分别存储到不同的磁盘上。

比如,更改数据目录到/mnt/data/cassandra目录下,这是挂装的一个不同的磁盘驱动器。

首先停掉cassandra

1
$ sudo service cassandra stop

然后修改/etc/cassandra/cassandra.yaml

1
2
data_file_directories:
- /mnt/data/cassandra

将/var/lib/cassandra/data目录下的所有东西全部拷贝或移动到/mnt/data/cassandra目录下

1
$ sudo -u cassandra cp -r /var/lib/cassandra/data/* /mnt/data/cassandra

1
$ sudo -u cassandra mv /var/lib/cassandra/data /mnt/data/cassandra

最后重新启动cassandra

1
$ sudo service cassandra start

===
[erq]

使用cassandra最最重要的事情不要忘记,架设一台时间服务器,所有的节点都与这台时间服务器定时同步,切记!
时间一致性对cassandra至关重要。

配置文件中添加如下行:

1
2
3
4
5
6
7
8
9
10
11
12
server {
...
location /wsapp/ {
proxy_pass http://wsbackend;

# proxy websocket reverse
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
...
}

References:
[1]NGINX as a WebSocket Proxy

===
[erq]