Jekyll2022-08-01T05:47:01+00:00https://www.izhizheng.org/atom.xml爱知笔记Whatever u do, Remember why you started.Zhizheng Zhang使用 maven-assembly-plugin 打包2018-08-17T05:29:01+00:002018-08-17T05:29:01+00:00https://www.izhizheng.org/post/maven-assembly-plugin<p>现在有这样一个需求,在一个 java 项目的源码根目录下增加一个 Dockerfile 文件,先把项目打包成一个完整的压缩包 your-app-bin.zip(包含 bin、config、lib 等目录),再把压缩包 your-app-bin.zip 和 Dockerfile 文件一起打包成另一个压缩包 your-app-docker.zip(your-app-bin.zip 和 Dockerfile 文件平级)。</p>
<p>因项目使用 maven 管理,并使用 maven-assembly-plugin 打包。可以在项目 pom.xml 中 maven-assembly-plugin 的配置下增加第二个打包配置文件。</p>
<!-- more -->
<h2 id="pomxml-中-maven-assembly-plugin-插件配置">pom.xml 中 maven-assembly-plugin 插件配置</h2>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"><!-- The configuration of maven-assembly-plugin --></span>
<span class="nt"><plugin></span>
<span class="nt"><groupId></span>org.apache.maven.plugins<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>maven-assembly-plugin<span class="nt"></artifactId></span>
<span class="nt"><version></span>2.4.1<span class="nt"></version></span>
<span class="c"><!-- The configuration of the plugin --></span>
<span class="nt"><configuration></span>
<span class="nt"><finalName></span>your-app<span class="nt"></finalName></span>
<span class="c"><!-- append assembly id in release file name --></span>
<span class="nt"><appendAssemblyId></span>true<span class="nt"></appendAssemblyId></span>
<span class="c"><!-- Specifies the configuration file of the assembly plugin --></span>
<span class="nt"><descriptors></span>
<span class="nt"><descriptor></span>src/main/assembly/bin.xml<span class="nt"></descriptor></span>
<span class="nt"><descriptor></span>src/main/assembly/docker.xml<span class="nt"></descriptor></span>
<span class="nt"></descriptors></span>
<span class="nt"></configuration></span>
<span class="nt"><executions></span>
<span class="nt"><execution></span>
<span class="nt"><id></span>make-assembly<span class="nt"></id></span>
<span class="nt"><phase></span>package<span class="nt"></phase></span>
<span class="nt"><goals></span>
<span class="nt"><goal></span>single<span class="nt"></goal></span>
<span class="nt"></goals></span>
<span class="nt"></execution></span>
<span class="nt"></executions></span>
<span class="nt"></plugin></span>
</code></pre></div></div>
<h2 id="binxml-内容">bin.xml 内容</h2>
<p>常规编写即可,没什么特殊要求。</p>
<h2 id="dockerxml-示例">docker.xml 示例</h2>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><assembly></span>
<span class="nt"><id></span>docker<span class="nt"></id></span>
<span class="nt"><formats></span>
<span class="nt"><format></span>zip<span class="nt"></format></span>
<span class="nt"></formats></span>
<span class="nt"><dependencySets></span>
<span class="nt"></dependencySets></span>
<span class="nt"><fileSets></span>
<span class="nt"><fileSet></span>
<span class="nt"><directory></span>${project.basedir}/target<span class="nt"></directory></span>
<span class="nt"><outputDirectory></span>.<span class="nt"></outputDirectory></span>
<span class="nt"><includes></span>
<span class="nt"><include></span>*.zip<span class="nt"></include></span>
<span class="nt"></includes></span>
<span class="nt"></fileSet></span>
<span class="nt"><fileSet></span>
<span class="nt"><directory></span>${project.basedir}<span class="nt"></directory></span>
<span class="nt"><outputDirectory></span>.<span class="nt"></outputDirectory></span>
<span class="nt"><includes></span>
<span class="nt"><include></span>Dockerfile<span class="nt"></include></span>
<span class="nt"></includes></span>
<span class="nt"></fileSet></span>
<span class="nt"></fileSets></span>
<span class="nt"></assembly></span>
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ul>
<li>
<p><a href="http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html" target="_blank" rel="nofollow noopener noreferrer">Apache Maven Assembly Plugin</a></p>
</li>
<li>
<p><a href="https://blog.csdn.net/u013174217/article/details/53300818" target="_blank" rel="nofollow noopener noreferrer">使用maven-assembly-plugin打包,assembly的语法介绍(同时打多个包、排除依赖包、文件更改别名、自定义路径)</a></p>
</li>
</ul>Zhizheng Zhang现在有这样一个需求,在一个 java 项目的源码根目录下增加一个 Dockerfile 文件,先把项目打包成一个完整的压缩包 your-app-bin.zip(包含 bin、config、lib 等目录),再把压缩包 your-app-bin.zip 和 Dockerfile 文件一起打包成另一个压缩包 your-app-docker.zip(your-app-bin.zip 和 Dockerfile 文件平级)。 因项目使用 maven 管理,并使用 maven-assembly-plugin 打包。可以在项目 pom.xml 中 maven-assembly-plugin 的配置下增加第二个打包配置文件。Linux 丢失或误删除 libc.so.6 的处理方法2018-05-08T09:33:01+00:002018-05-08T09:33:01+00:00https://www.izhizheng.org/post/linux-missing-libc.so.6<p>因为要编写 markdown 并生成 html,选择安装 Atom。先是下载了最新版 1.26.1,安装后运行提示主机上 gblic 过时。又下载了一个较旧的版本 1.12.7,安装后运行还是提示主机上 gblic 过时,需要 glibc-2.14。因此决定升级主机 glibc 版本。</p>
<!-- more -->
<h2 id="环境说明">环境说明</h2>
<ul>
<li>操作系统:Debian 7 (wheezy)</li>
<li>glibc: glibc-2.13</li>
<li>Atom: 1.26.1 & 1.12.7</li>
</ul>
<h2 id="升级-glibc-到新版本">升级 glibc 到新版本</h2>
<ol>
<li>下载 <a href="http://ftp.gnu.org/gnu/glibc/glibc-2.14.1.tar.gz" target="_blank" rel="nofollow noopener noreferrer">http://ftp.gnu.org/gnu/glibc/glibc-2.14.1.tar.gz</a></li>
<li>
<p>编译</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nb">cd</span> /builds
<span class="nb">tar </span>zxf /path/to/glibc-2.14.1.tar.gz
<span class="nb">cd</span> /builds/glibc-2.14.1
<span class="nb">mkdir </span>build
<span class="nb">cd </span>build
../configure <span class="nt">--prefix</span><span class="o">=</span>/opt/glibc/2.14.1
<span class="nb">sudo </span>apt-get <span class="nb">install </span>gawk <span class="c"># 解决 make 报错</span>
make <span class="nt">-j4</span>
<span class="nb">sudo </span>make <span class="nb">install</span>
</code></pre></div> </div>
</li>
<li>
<p>修改系统链接指向新动态库</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nb">cd</span> /lib/x86_64-linux-gnu
<span class="nb">unlink </span>libc.so.6
<span class="nb">ln</span> <span class="nt">-s</span> /opt/glibc/2.14.1/lib/libc-2.14.1.so libc.so.6 <span class="c"># 命令报错,提示找不到 libc.so.6,其它好多系统内置命令也无法运行</span>
</code></pre></div> </div>
</li>
</ol>
<h2 id="找不到-libcso6-问题解决">找不到 libc.so.6 问题解决</h2>
<ol>
<li>使用光盘修复系统</li>
<li>
<p>执行以下命令</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> LD_PRELOAD=/lib/x86_64-linux-gnu/libc-2.13.so ln -s /opt/glibc/2.14.1/lib/libc-2.14.1.so libc.so.6
</code></pre></div> </div>
<p>或</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> LD_PRELOAD=/opt/glibc/2.14.1/lib/libc-2.14.1.so ln -s /opt/glibc/2.14.1/lib/libc-2.14.1.so libc.so.6
</code></pre></div> </div>
</li>
</ol>
<p>推荐使用第 2 种方法。</p>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="http://www.cnblogs.com/qingchen1984/p/5731419.html" target="_blank" rel="nofollow noopener noreferrer">误删除libc.so.6的解决方法</a></li>
</ul>Zhizheng Zhang因为要编写 markdown 并生成 html,选择安装 Atom。先是下载了最新版 1.26.1,安装后运行提示主机上 gblic 过时。又下载了一个较旧的版本 1.12.7,安装后运行还是提示主机上 gblic 过时,需要 glibc-2.14。因此决定升级主机 glibc 版本。Excel 自动填充数据2018-04-16T17:01:07+00:002018-04-16T17:01:07+00:00https://www.izhizheng.org/post/autofill-in-excel<p>现在有一个需求,在 excel 表格某一列中要填入 80000 个连续的手机号码,从 18900000001 到 18900080000。</p>
<h2 id="手工录入">手工录入</h2>
<ul>
<li>一个号码一个号码地录入,十分耗时,只录入少数数据时适用。本方法对于填充 80000 个单元格的数据不适用</li>
<li>先录入第一个号码,再通过托动单元格右下角的填充柄填充数据。本方法对于填充 80000 个单元格的数据也不太适用</li>
</ul>
<h2 id="序列填充">序列填充</h2>
<p>在单元格内填入第一个手机号码 18900000001</p>
<!-- more -->
<p><img src="/uploads/2018/04/excel-autofill_1.png" alt="excel-autofill_1.png" /></p>
<p>在菜单中选择“编辑”->“填充”->“序列”</p>
<p><img src="/uploads/2018/04/excel-autofill_2.png" alt="excel-autofill_2.png" /></p>
<p>在弹出的窗口中,序列产生在选择“列”,类型选择“等差数列”,步长值填写“1”,终止值填写“18900080000“,点击确定按钮</p>
<p><img src="/uploads/2018/04/excel-autofill_3.png" alt="excel-autofill_3.png" /></p>
<p>序列填充完成后,可以看到,第一个值为 18900000001,最后一个值为 18900080000</p>
<p><img src="/uploads/2018/04/excel-autofill_4.png" alt="excel-autofill_4.png" />
<img src="/uploads/2018/04/excel-autofill_5.png" alt="excel-autofill_5.png" /></p>
<h2 id="注意事项">注意事项</h2>
<ul>
<li>Excel 2003(.xls)最大行数为 65536,Excel 2007(.xlsx)最大行数为 1048576</li>
<li>Excel 2003(.xls)最大列数为 256,Excel 2007(.xlsx)最大列数为 16384</li>
</ul>Zhizheng Zhang现在有一个需求,在 excel 表格某一列中要填入 80000 个连续的手机号码,从 18900000001 到 18900080000。 手工录入 一个号码一个号码地录入,十分耗时,只录入少数数据时适用。本方法对于填充 80000 个单元格的数据不适用 先录入第一个号码,再通过托动单元格右下角的填充柄填充数据。本方法对于填充 80000 个单元格的数据也不太适用 序列填充 在单元格内填入第一个手机号码 18900000001Linux 端口转发(映射)2018-04-14T09:24:01+00:002018-04-14T09:24:01+00:00https://www.izhizheng.org/post/linux-port-forwarding<p>当内网集群只开放一台主机(一般称为跳板机或中转机)可以被外界访问时,我们在跳板机或中转机上可以通过 ssh 连接到其它内网主机。</p>
<p>但是,当我们要通过本地浏览器访问某台内网主机上的 web 程序(或通过数据库客户端访问某台内网主机上的数据库)时,要如何做呢?</p>
<p>一种可靠的方法是通过端口转发(映射),架构示意图如下:</p>
<!-- more -->
<p><img src="/uploads/2018/04/port-forwarding_arch.png" alt="port-forwarding_arch.png" /></p>
<p>具体可以通过 SecureCrt 或 Xshell 实现,具体方法如下:</p>
<h2 id="securecrt">SecureCrt</h2>
<p>确定连接跳板机或中转机的端口(当使用安全网关程序登录时,端口是随机的),可以看出 port 是 3551</p>
<p><img src="/uploads/2018/04/port-forwarding_1.png" alt="port-forwarding_1.png" />
<img src="/uploads/2018/04/port-forwarding_2.png" alt="port-forwarding_2.png" /></p>
<p>新建一个会话,ip 127.0.0.1,端口 3551,并将所有的端口转发(映射)都配置上</p>
<p><img src="/uploads/2018/04/port-forwarding_3.png" alt="port-forwarding_3.png" />
<img src="/uploads/2018/04/port-forwarding_4.png" alt="port-forwarding_4.png" />
<img src="/uploads/2018/04/port-forwarding_5.png" alt="port-forwarding_5.png" />
<img src="/uploads/2018/04/port-forwarding_6.png" alt="port-forwarding_6.png" /></p>
<p>连接刚建立的会话,连接成功后,就可以通过本机访问 web 程序或数据库了</p>
<blockquote>
<p>http://127.0.0.106:8080/</p>
</blockquote>
<blockquote>
<p>jdbc:mysql://127.0.0.15:3306?test</p>
</blockquote>
<h2 id="xshell">Xshell</h2>
<p>Xshell 操作和 SecureCrt 类似,不再赘述。</p>
<h2 id="重要说明">重要说明</h2>
<p>跳板机或中转机连接关闭后,端口转发(映射)全部失效。</p>Zhizheng Zhang当内网集群只开放一台主机(一般称为跳板机或中转机)可以被外界访问时,我们在跳板机或中转机上可以通过 ssh 连接到其它内网主机。 但是,当我们要通过本地浏览器访问某台内网主机上的 web 程序(或通过数据库客户端访问某台内网主机上的数据库)时,要如何做呢? 一种可靠的方法是通过端口转发(映射),架构示意图如下:Linux 用户密码过期2018-04-02T13:21:01+00:002018-04-02T13:21:01+00:00https://www.izhizheng.org/post/linux-password-expire<p>今天,在工作中遇到了 linux 用户密码过期的问题,使用 chage 命令可以设置用户账号和密码的有效期。</p>
<p>chage 命令用法如下</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user@server:~<span class="nv">$ </span>chage <span class="nt">-h</span>
Usage: chage <span class="o">[</span>options] LOGIN
Options:
<span class="nt">-d</span>, <span class="nt">--lastday</span> LAST_DAY <span class="nb">set date </span>of last password change to LAST_DAY
<span class="nt">-E</span>, <span class="nt">--expiredate</span> EXPIRE_DATE <span class="nb">set </span>account expiration <span class="nb">date </span>to EXPIRE_DATE
<span class="nt">-h</span>, <span class="nt">--help</span> display this <span class="nb">help </span>message and <span class="nb">exit</span>
<span class="nt">-I</span>, <span class="nt">--inactive</span> INACTIVE <span class="nb">set </span>password inactive after expiration
to INACTIVE
<span class="nt">-l</span>, <span class="nt">--list</span> show account aging information
<span class="nt">-m</span>, <span class="nt">--mindays</span> MIN_DAYS <span class="nb">set </span>minimum number of days before password
change to MIN_DAYS
<span class="nt">-M</span>, <span class="nt">--maxdays</span> MAX_DAYS <span class="nb">set </span>maximim number of days before password
change to MAX_DAYS
<span class="nt">-R</span>, <span class="nt">--root</span> CHROOT_DIR directory to <span class="nb">chroot </span>into
<span class="nt">-W</span>, <span class="nt">--warndays</span> WARN_DAYS <span class="nb">set </span>expiration warning days to WARN_DAYS
</code></pre></div></div>
<p>其中,-E 设置账号过期时间,-M 设置密码过期时间,-I 设置密码失效时间。</p>
<!-- more -->
<p>用户 user 查看自己账号和密码的有效期</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user@server:~<span class="nv">$ </span>chage <span class="nt">-l</span> user
Last password change : Nov 28, 2016
Password expires : never
Password inactive : never
Account expires : never
Minimum number of days between password change : <span class="nt">-1</span>
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
</code></pre></div></div>
<p>设置账号 user 的过期时间为 2018 年 12 月 31 日</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@server:~# chage <span class="nt">-E</span> <span class="s2">"2018-12-31"</span> user
</code></pre></div></div>
<p>设置账号 user 永不过期</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@server:~# chage <span class="nt">-E</span> <span class="nt">-1</span> user
</code></pre></div></div>
<p>设置账号 user 立即过期</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@server:~# chage <span class="nt">-E</span> 0 user
</code></pre></div></div>
<p>设置账号 user 的密码在 MAX_DAYS=30 天后过期,此时必须先修改密码才能登录系统</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@server:~# chage <span class="nt">-M</span> 30 user
</code></pre></div></div>
<p>设置账号 user 的密码在 MAX_DAYS+3 天后失效,此时不能登录系统,只能求助于管理员</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@server:~# chage <span class="nt">-I</span> 3 user
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="http://m.blog.itpub.net/15498/viewspace-2070548/" target="_blank" rel="nofollow noopener noreferrer">如何设置Linux普通用户密码永不过期</a></li>
</ul>Zhizheng Zhang今天,在工作中遇到了 linux 用户密码过期的问题,使用 chage 命令可以设置用户账号和密码的有效期。 chage 命令用法如下 user@server:~$ chage -h Usage: chage [options] LOGIN Options: -d, --lastday LAST_DAY set date of last password change to LAST_DAY -E, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE -h, --help display this help message and exit -I, --inactive INACTIVE set password inactive after expiration to INACTIVE -l, --list show account aging information -m, --mindays MIN_DAYS set minimum number of days before password change to MIN_DAYS -M, --maxdays MAX_DAYS set maximim number of days before password change to MAX_DAYS -R, --root CHROOT_DIR directory to chroot into -W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS 其中,-E 设置账号过期时间,-M 设置密码过期时间,-I 设置密码失效时间。Redis 集群搭建2018-04-02T10:05:01+00:002018-04-02T10:05:01+00:00https://www.izhizheng.org/post/redis-cluster<h2 id="源码下载">源码下载</h2>
<p><a href="http://download.redis.io/releases/redis-3.2.11.tar.gz" target="_blank" rel="nofollow noopener noreferrer">http://download.redis.io/releases/redis-3.2.11.tar.gz</a></p>
<h2 id="源码编译">源码编译</h2>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tar </span>zxvf redis-3.2.11.tar.gz
<span class="nb">cd</span> ~/redis-3.2.11
make
</code></pre></div></div>
<h2 id="集群规划及配置">集群规划及配置</h2>
<p>创建集群目录,将编译好的命令文件复制到 bin 目录</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> /usr/local/redis-cluster/bin
<span class="nb">cd</span> ~/redis-3.2.11/src
<span class="nb">cp </span>mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server redis-trib.rb /usr/local/redis-cluster/bin
</code></pre></div></div>
<!-- more -->
<p>创建 6 个 redis 实例目录,并将 redis 配置文件复制到各实例目录</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> /usr/local/redis-cluster
<span class="nb">mkdir</span> <span class="nt">-p</span> 9001/data
<span class="nb">mkdir</span> <span class="nt">-p</span> 9002/data
<span class="nb">mkdir</span> <span class="nt">-p</span> 9003/data
<span class="nb">mkdir</span> <span class="nt">-p</span> 9004/data
<span class="nb">mkdir</span> <span class="nt">-p</span> 9005/data
<span class="nb">mkdir</span> <span class="nt">-p</span> 9006/data
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9001
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9002
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9003
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9004
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9005
<span class="nb">cp</span> ~/redis-3.2.11/redis.conf 9006
</code></pre></div></div>
<p>修改各 redis 实例的配置文件,以 9001 实例为例,bind 为本机 ip</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>daemonize yes
pidfile /usr/local/redis-cluster/9001/redis.pid
bind 192.168.1.6
port 9001
dir /usr/local/redis-cluster/9001/data
appendonly yes
cluster-enabled yes
cluster-config-file nodes-9001.conf
cluster-node-timeout 15000
</code></pre></div></div>
<p>9002-9006 实例配置同上,只是将其中的 9001 替换为相应的端口号。</p>
<h2 id="实例启动及测试">实例启动及测试</h2>
<p>启动实例</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9001/redis.conf
/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9002/redis.conf
/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9003/redis.conf
/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9004/redis.conf
/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9005/redis.conf
/usr/local/redis-cluster/bin/redis-server /usr/local/redis-cluster/9006/redis.conf
</code></pre></div></div>
<p>连接实例,确认各实例正常启动</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9001
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9002
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9003
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9004
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9005
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9006
</code></pre></div></div>
<h2 id="集群构建及测试">集群构建及测试</h2>
<p>安装 ruby 及 redis 依赖</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt-get <span class="nb">install </span>ruby
gem <span class="nb">install </span>redis
</code></pre></div></div>
<p>将单独的 redis 实例构建成集群(三主三从)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/redis-cluster/bin/redis-trib.rb create <span class="nt">--replicas</span> 1 192.168.1.6:9001 192.168.1.6:9002 192.168.1.6:9003 192.168.1.6:9004 192.168.1.6:9005 192.168.1.6:9006
</code></pre></div></div>
<p>连接集群节点,注意比连接单实例时多了一个 -c 参数</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9001 <span class="nt">-c</span>
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9002 <span class="nt">-c</span>
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9003 <span class="nt">-c</span>
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9004 <span class="nt">-c</span>
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9005 <span class="nt">-c</span>
/usr/local/redis-cluster/bin/redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9006 <span class="nt">-c</span>
</code></pre></div></div>
<p>查看集群信息</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9001 <span class="nt">-c</span>
192.168.1.6:9001> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:55
cluster_stats_messages_received:50
192.168.1.6:9001> cluster nodes
e74db54eb4fa9dde324988e44bb3919129f944c8 192.168.1.6:9006 slave de0928f00ac377bf5b7806d088808f31804923eb 0 1522674425815 6 connected
186a18ae13203946253b537cfdab549b3be5282d 192.168.1.6:9005 slave 761269f61d3f95d3937b5b3451ea73f979aa40e6 0 1522674423811 5 connected
3e58b504f1419cf770313daf11f480bf48dd34a0 192.168.1.6:9001 myself,master - 0 0 1 connected 0-5460
6a1327d2385b0e270a9d1fa63bae3c14c879625e 192.168.1.6:9004 slave 3e58b504f1419cf770313daf11f480bf48dd34a0 0 1522674424813 4 connected
761269f61d3f95d3937b5b3451ea73f979aa40e6 192.168.1.6:9002 master - 0 1522674422809 2 connected 5461-10922
de0928f00ac377bf5b7806d088808f31804923eb 192.168.1.6:9003 master - 0 1522674426818 3 connected 10923-16383
</code></pre></div></div>
<h2 id="客户端连接读写">客户端连接读写</h2>
<p>客户端以 redis-cli 为例,数据读写测试脚本</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./redis-cli <span class="nt">-h</span> 192.168.1.6 <span class="nt">-p</span> 9001 <span class="nt">-c</span>
192.168.1.6:9001> <span class="nb">set </span>key1 value1
-> Redirected to slot <span class="o">[</span>9189] located at 192.168.1.6:9002
OK
192.168.1.6:9002> get key1
<span class="s2">"value1"</span>
</code></pre></div></div>
<p>客户端以 jedis 为例,当前版本</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>redis.clients<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>jedis<span class="nt"></artifactId></span>
<span class="nt"><version></span>2.9.0<span class="nt"></version></span>
<span class="nt"><type></span>jar<span class="nt"></type></span>
<span class="nt"><scope></span>compile<span class="nt"></scope></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>jedis 数据读写测试代码</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Set</span><span class="o"><</span><span class="nc">HostAndPort</span><span class="o">></span> <span class="n">jedisClusterNodes</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashSet</span><span class="o"><</span><span class="nc">HostAndPort</span><span class="o">>();</span>
<span class="c1">// Jedis Cluster will attempt to discover cluster nodes automatically</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9001</span><span class="o">));</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9002</span><span class="o">));</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9003</span><span class="o">));</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9004</span><span class="o">));</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9005</span><span class="o">));</span>
<span class="n">jedisClusterNodes</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">HostAndPort</span><span class="o">(</span><span class="s">"192.168.1.6"</span><span class="o">,</span> <span class="mi">9006</span><span class="o">));</span>
<span class="nc">JedisCluster</span> <span class="n">jc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JedisCluster</span><span class="o">(</span><span class="n">jedisClusterNodes</span><span class="o">);</span>
<span class="n">jc</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"key"</span><span class="o">,</span> <span class="s">"value"</span><span class="o">);</span>
<span class="nc">String</span> <span class="n">value</span> <span class="o">=</span> <span class="n">jc</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"key"</span><span class="o">);</span>
<span class="c1">// jc.close();</span>
</code></pre></div></div>
<h2 id="槽分配及位置确定">槽分配及位置确定</h2>
<p>从上面集群信息中可以看出,主从实例 9001 9004 分配的槽范围为 0-5460,主从实例 9002 9005 分配的槽范围为 5461-10922,主从实例 9003 9006 分配的槽范围为 10923-16383。</p>
<p>当用户通过客户端(redis-cli 或 jedis)向集群存入键值对时,数据存储的槽编号通过 key 计算出来,算法 CRC16(key) % 16384。</p>
<p>算法 CRC16(key) % 16384 的 java 代码实现</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/**
* 计算键 key 要放入哪个槽
*
* @param key 键名
* @return slot 槽编号
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">slot</span><span class="o">(</span><span class="nc">String</span> <span class="n">key</span><span class="o">){</span>
<span class="kt">int</span> <span class="n">slot</span> <span class="o">=</span> <span class="n">crc16</span><span class="o">(</span><span class="n">key</span><span class="o">)</span> <span class="o">%</span> <span class="mi">16384</span><span class="o">;</span>
<span class="k">return</span> <span class="n">slot</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* 计算键 key 的 crc16 值
*
* @param key 键名
* @return crc16 值
* @see ~/redis-3.2.11/src/cluster.c and ~/redis-3.2.11/src/crc16.c
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="nf">crc16</span><span class="o">(</span><span class="nc">String</span> <span class="n">key</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">int</span><span class="o">[]</span> <span class="n">table</span> <span class="o">=</span> <span class="o">{</span>
<span class="mh">0x0000</span><span class="o">,</span><span class="mh">0x1021</span><span class="o">,</span><span class="mh">0x2042</span><span class="o">,</span><span class="mh">0x3063</span><span class="o">,</span><span class="mh">0x4084</span><span class="o">,</span><span class="mh">0x50a5</span><span class="o">,</span><span class="mh">0x60c6</span><span class="o">,</span><span class="mh">0x70e7</span><span class="o">,</span>
<span class="mh">0x8108</span><span class="o">,</span><span class="mh">0x9129</span><span class="o">,</span><span class="mh">0xa14a</span><span class="o">,</span><span class="mh">0xb16b</span><span class="o">,</span><span class="mh">0xc18c</span><span class="o">,</span><span class="mh">0xd1ad</span><span class="o">,</span><span class="mh">0xe1ce</span><span class="o">,</span><span class="mh">0xf1ef</span><span class="o">,</span>
<span class="mh">0x1231</span><span class="o">,</span><span class="mh">0x0210</span><span class="o">,</span><span class="mh">0x3273</span><span class="o">,</span><span class="mh">0x2252</span><span class="o">,</span><span class="mh">0x52b5</span><span class="o">,</span><span class="mh">0x4294</span><span class="o">,</span><span class="mh">0x72f7</span><span class="o">,</span><span class="mh">0x62d6</span><span class="o">,</span>
<span class="mh">0x9339</span><span class="o">,</span><span class="mh">0x8318</span><span class="o">,</span><span class="mh">0xb37b</span><span class="o">,</span><span class="mh">0xa35a</span><span class="o">,</span><span class="mh">0xd3bd</span><span class="o">,</span><span class="mh">0xc39c</span><span class="o">,</span><span class="mh">0xf3ff</span><span class="o">,</span><span class="mh">0xe3de</span><span class="o">,</span>
<span class="mh">0x2462</span><span class="o">,</span><span class="mh">0x3443</span><span class="o">,</span><span class="mh">0x0420</span><span class="o">,</span><span class="mh">0x1401</span><span class="o">,</span><span class="mh">0x64e6</span><span class="o">,</span><span class="mh">0x74c7</span><span class="o">,</span><span class="mh">0x44a4</span><span class="o">,</span><span class="mh">0x5485</span><span class="o">,</span>
<span class="mh">0xa56a</span><span class="o">,</span><span class="mh">0xb54b</span><span class="o">,</span><span class="mh">0x8528</span><span class="o">,</span><span class="mh">0x9509</span><span class="o">,</span><span class="mh">0xe5ee</span><span class="o">,</span><span class="mh">0xf5cf</span><span class="o">,</span><span class="mh">0xc5ac</span><span class="o">,</span><span class="mh">0xd58d</span><span class="o">,</span>
<span class="mh">0x3653</span><span class="o">,</span><span class="mh">0x2672</span><span class="o">,</span><span class="mh">0x1611</span><span class="o">,</span><span class="mh">0x0630</span><span class="o">,</span><span class="mh">0x76d7</span><span class="o">,</span><span class="mh">0x66f6</span><span class="o">,</span><span class="mh">0x5695</span><span class="o">,</span><span class="mh">0x46b4</span><span class="o">,</span>
<span class="mh">0xb75b</span><span class="o">,</span><span class="mh">0xa77a</span><span class="o">,</span><span class="mh">0x9719</span><span class="o">,</span><span class="mh">0x8738</span><span class="o">,</span><span class="mh">0xf7df</span><span class="o">,</span><span class="mh">0xe7fe</span><span class="o">,</span><span class="mh">0xd79d</span><span class="o">,</span><span class="mh">0xc7bc</span><span class="o">,</span>
<span class="mh">0x48c4</span><span class="o">,</span><span class="mh">0x58e5</span><span class="o">,</span><span class="mh">0x6886</span><span class="o">,</span><span class="mh">0x78a7</span><span class="o">,</span><span class="mh">0x0840</span><span class="o">,</span><span class="mh">0x1861</span><span class="o">,</span><span class="mh">0x2802</span><span class="o">,</span><span class="mh">0x3823</span><span class="o">,</span>
<span class="mh">0xc9cc</span><span class="o">,</span><span class="mh">0xd9ed</span><span class="o">,</span><span class="mh">0xe98e</span><span class="o">,</span><span class="mh">0xf9af</span><span class="o">,</span><span class="mh">0x8948</span><span class="o">,</span><span class="mh">0x9969</span><span class="o">,</span><span class="mh">0xa90a</span><span class="o">,</span><span class="mh">0xb92b</span><span class="o">,</span>
<span class="mh">0x5af5</span><span class="o">,</span><span class="mh">0x4ad4</span><span class="o">,</span><span class="mh">0x7ab7</span><span class="o">,</span><span class="mh">0x6a96</span><span class="o">,</span><span class="mh">0x1a71</span><span class="o">,</span><span class="mh">0x0a50</span><span class="o">,</span><span class="mh">0x3a33</span><span class="o">,</span><span class="mh">0x2a12</span><span class="o">,</span>
<span class="mh">0xdbfd</span><span class="o">,</span><span class="mh">0xcbdc</span><span class="o">,</span><span class="mh">0xfbbf</span><span class="o">,</span><span class="mh">0xeb9e</span><span class="o">,</span><span class="mh">0x9b79</span><span class="o">,</span><span class="mh">0x8b58</span><span class="o">,</span><span class="mh">0xbb3b</span><span class="o">,</span><span class="mh">0xab1a</span><span class="o">,</span>
<span class="mh">0x6ca6</span><span class="o">,</span><span class="mh">0x7c87</span><span class="o">,</span><span class="mh">0x4ce4</span><span class="o">,</span><span class="mh">0x5cc5</span><span class="o">,</span><span class="mh">0x2c22</span><span class="o">,</span><span class="mh">0x3c03</span><span class="o">,</span><span class="mh">0x0c60</span><span class="o">,</span><span class="mh">0x1c41</span><span class="o">,</span>
<span class="mh">0xedae</span><span class="o">,</span><span class="mh">0xfd8f</span><span class="o">,</span><span class="mh">0xcdec</span><span class="o">,</span><span class="mh">0xddcd</span><span class="o">,</span><span class="mh">0xad2a</span><span class="o">,</span><span class="mh">0xbd0b</span><span class="o">,</span><span class="mh">0x8d68</span><span class="o">,</span><span class="mh">0x9d49</span><span class="o">,</span>
<span class="mh">0x7e97</span><span class="o">,</span><span class="mh">0x6eb6</span><span class="o">,</span><span class="mh">0x5ed5</span><span class="o">,</span><span class="mh">0x4ef4</span><span class="o">,</span><span class="mh">0x3e13</span><span class="o">,</span><span class="mh">0x2e32</span><span class="o">,</span><span class="mh">0x1e51</span><span class="o">,</span><span class="mh">0x0e70</span><span class="o">,</span>
<span class="mh">0xff9f</span><span class="o">,</span><span class="mh">0xefbe</span><span class="o">,</span><span class="mh">0xdfdd</span><span class="o">,</span><span class="mh">0xcffc</span><span class="o">,</span><span class="mh">0xbf1b</span><span class="o">,</span><span class="mh">0xaf3a</span><span class="o">,</span><span class="mh">0x9f59</span><span class="o">,</span><span class="mh">0x8f78</span><span class="o">,</span>
<span class="mh">0x9188</span><span class="o">,</span><span class="mh">0x81a9</span><span class="o">,</span><span class="mh">0xb1ca</span><span class="o">,</span><span class="mh">0xa1eb</span><span class="o">,</span><span class="mh">0xd10c</span><span class="o">,</span><span class="mh">0xc12d</span><span class="o">,</span><span class="mh">0xf14e</span><span class="o">,</span><span class="mh">0xe16f</span><span class="o">,</span>
<span class="mh">0x1080</span><span class="o">,</span><span class="mh">0x00a1</span><span class="o">,</span><span class="mh">0x30c2</span><span class="o">,</span><span class="mh">0x20e3</span><span class="o">,</span><span class="mh">0x5004</span><span class="o">,</span><span class="mh">0x4025</span><span class="o">,</span><span class="mh">0x7046</span><span class="o">,</span><span class="mh">0x6067</span><span class="o">,</span>
<span class="mh">0x83b9</span><span class="o">,</span><span class="mh">0x9398</span><span class="o">,</span><span class="mh">0xa3fb</span><span class="o">,</span><span class="mh">0xb3da</span><span class="o">,</span><span class="mh">0xc33d</span><span class="o">,</span><span class="mh">0xd31c</span><span class="o">,</span><span class="mh">0xe37f</span><span class="o">,</span><span class="mh">0xf35e</span><span class="o">,</span>
<span class="mh">0x02b1</span><span class="o">,</span><span class="mh">0x1290</span><span class="o">,</span><span class="mh">0x22f3</span><span class="o">,</span><span class="mh">0x32d2</span><span class="o">,</span><span class="mh">0x4235</span><span class="o">,</span><span class="mh">0x5214</span><span class="o">,</span><span class="mh">0x6277</span><span class="o">,</span><span class="mh">0x7256</span><span class="o">,</span>
<span class="mh">0xb5ea</span><span class="o">,</span><span class="mh">0xa5cb</span><span class="o">,</span><span class="mh">0x95a8</span><span class="o">,</span><span class="mh">0x8589</span><span class="o">,</span><span class="mh">0xf56e</span><span class="o">,</span><span class="mh">0xe54f</span><span class="o">,</span><span class="mh">0xd52c</span><span class="o">,</span><span class="mh">0xc50d</span><span class="o">,</span>
<span class="mh">0x34e2</span><span class="o">,</span><span class="mh">0x24c3</span><span class="o">,</span><span class="mh">0x14a0</span><span class="o">,</span><span class="mh">0x0481</span><span class="o">,</span><span class="mh">0x7466</span><span class="o">,</span><span class="mh">0x6447</span><span class="o">,</span><span class="mh">0x5424</span><span class="o">,</span><span class="mh">0x4405</span><span class="o">,</span>
<span class="mh">0xa7db</span><span class="o">,</span><span class="mh">0xb7fa</span><span class="o">,</span><span class="mh">0x8799</span><span class="o">,</span><span class="mh">0x97b8</span><span class="o">,</span><span class="mh">0xe75f</span><span class="o">,</span><span class="mh">0xf77e</span><span class="o">,</span><span class="mh">0xc71d</span><span class="o">,</span><span class="mh">0xd73c</span><span class="o">,</span>
<span class="mh">0x26d3</span><span class="o">,</span><span class="mh">0x36f2</span><span class="o">,</span><span class="mh">0x0691</span><span class="o">,</span><span class="mh">0x16b0</span><span class="o">,</span><span class="mh">0x6657</span><span class="o">,</span><span class="mh">0x7676</span><span class="o">,</span><span class="mh">0x4615</span><span class="o">,</span><span class="mh">0x5634</span><span class="o">,</span>
<span class="mh">0xd94c</span><span class="o">,</span><span class="mh">0xc96d</span><span class="o">,</span><span class="mh">0xf90e</span><span class="o">,</span><span class="mh">0xe92f</span><span class="o">,</span><span class="mh">0x99c8</span><span class="o">,</span><span class="mh">0x89e9</span><span class="o">,</span><span class="mh">0xb98a</span><span class="o">,</span><span class="mh">0xa9ab</span><span class="o">,</span>
<span class="mh">0x5844</span><span class="o">,</span><span class="mh">0x4865</span><span class="o">,</span><span class="mh">0x7806</span><span class="o">,</span><span class="mh">0x6827</span><span class="o">,</span><span class="mh">0x18c0</span><span class="o">,</span><span class="mh">0x08e1</span><span class="o">,</span><span class="mh">0x3882</span><span class="o">,</span><span class="mh">0x28a3</span><span class="o">,</span>
<span class="mh">0xcb7d</span><span class="o">,</span><span class="mh">0xdb5c</span><span class="o">,</span><span class="mh">0xeb3f</span><span class="o">,</span><span class="mh">0xfb1e</span><span class="o">,</span><span class="mh">0x8bf9</span><span class="o">,</span><span class="mh">0x9bd8</span><span class="o">,</span><span class="mh">0xabbb</span><span class="o">,</span><span class="mh">0xbb9a</span><span class="o">,</span>
<span class="mh">0x4a75</span><span class="o">,</span><span class="mh">0x5a54</span><span class="o">,</span><span class="mh">0x6a37</span><span class="o">,</span><span class="mh">0x7a16</span><span class="o">,</span><span class="mh">0x0af1</span><span class="o">,</span><span class="mh">0x1ad0</span><span class="o">,</span><span class="mh">0x2ab3</span><span class="o">,</span><span class="mh">0x3a92</span><span class="o">,</span>
<span class="mh">0xfd2e</span><span class="o">,</span><span class="mh">0xed0f</span><span class="o">,</span><span class="mh">0xdd6c</span><span class="o">,</span><span class="mh">0xcd4d</span><span class="o">,</span><span class="mh">0xbdaa</span><span class="o">,</span><span class="mh">0xad8b</span><span class="o">,</span><span class="mh">0x9de8</span><span class="o">,</span><span class="mh">0x8dc9</span><span class="o">,</span>
<span class="mh">0x7c26</span><span class="o">,</span><span class="mh">0x6c07</span><span class="o">,</span><span class="mh">0x5c64</span><span class="o">,</span><span class="mh">0x4c45</span><span class="o">,</span><span class="mh">0x3ca2</span><span class="o">,</span><span class="mh">0x2c83</span><span class="o">,</span><span class="mh">0x1ce0</span><span class="o">,</span><span class="mh">0x0cc1</span><span class="o">,</span>
<span class="mh">0xef1f</span><span class="o">,</span><span class="mh">0xff3e</span><span class="o">,</span><span class="mh">0xcf5d</span><span class="o">,</span><span class="mh">0xdf7c</span><span class="o">,</span><span class="mh">0xaf9b</span><span class="o">,</span><span class="mh">0xbfba</span><span class="o">,</span><span class="mh">0x8fd9</span><span class="o">,</span><span class="mh">0x9ff8</span><span class="o">,</span>
<span class="mh">0x6e17</span><span class="o">,</span><span class="mh">0x7e36</span><span class="o">,</span><span class="mh">0x4e55</span><span class="o">,</span><span class="mh">0x5e74</span><span class="o">,</span><span class="mh">0x2e93</span><span class="o">,</span><span class="mh">0x3eb2</span><span class="o">,</span><span class="mh">0x0ed1</span><span class="o">,</span><span class="mh">0x1ef0</span>
<span class="o">};</span>
<span class="kt">byte</span><span class="o">[]</span> <span class="n">bytes</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="na">getBytes</span><span class="o">();</span>
<span class="kt">int</span> <span class="n">crc</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="o">;</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">byte</span> <span class="n">b</span> <span class="o">:</span> <span class="n">bytes</span><span class="o">)</span> <span class="o">{</span>
<span class="n">crc</span> <span class="o">=</span> <span class="o">(</span><span class="n">crc</span> <span class="o"><<</span> <span class="mi">8</span><span class="o">)</span> <span class="o">^</span> <span class="n">table</span><span class="o">[((</span><span class="n">crc</span> <span class="o">>></span> <span class="mi">8</span><span class="o">)</span> <span class="o">^</span> <span class="n">b</span><span class="o">)</span> <span class="o">&</span> <span class="mh">0x00FF</span><span class="o">];</span>
<span class="o">}</span>
<span class="n">crc</span> <span class="o">=</span> <span class="n">crc</span> <span class="o">&</span> <span class="mh">0x3FFF</span><span class="o">;</span>
<span class="k">return</span> <span class="n">crc</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">String</span> <span class="n">key</span> <span class="o">=</span> <span class="s">"key1"</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">slot</span> <span class="o">=</span> <span class="n">slot</span><span class="o">(</span><span class="n">key</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">"slot="</span> <span class="o">+</span> <span class="n">slot</span><span class="o">);</span> <span class="c1">// 输出 slot=9189</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="http://www.cnblogs.com/mafly/p/redis_cluster.html" target="_blank" rel="nofollow noopener noreferrer">Redis 集群搭建详细指南</a></li>
</ul>Zhizheng Zhang源码下载 http://download.redis.io/releases/redis-3.2.11.tar.gz 源码编译 tar zxvf redis-3.2.11.tar.gz cd ~/redis-3.2.11 make 集群规划及配置 创建集群目录,将编译好的命令文件复制到 bin 目录 mkdir -p /usr/local/redis-cluster/bin cd ~/redis-3.2.11/src cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server redis-trib.rb /usr/local/redis-cluster/binLinux su 命令2018-02-02T09:54:01+00:002018-02-02T09:54:01+00:00https://www.izhizheng.org/post/linux-command-su<p>今天一个同事问了我一个 linux 相关的问题,在服务器上用 root 用户执行如下命令</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /elasticsearch/elasticsearch-2.3.2/bin && su elasticsearch && ./elasticsearch -d
</code></pre></div></div>
<blockquote>
<p>好像执行./elasticsearch -d时,还是在root用户</p>
</blockquote>
<p>根据他说的情况,我想到 su 是有命令参数的,根据他的命令,我修改了一下</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su - elasticsearch -c "cd /elasticsearch/elasticsearch-2.3.2/bin && ./elasticsearch -d"
</code></pre></div></div>
<p>发给他后,他在自己的环境执行后,结果确实成功了。</p>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="http://blog.csdn.net/linucle/article/details/43967237" target="_blank" rel="nofollow noopener noreferrer">shell不能执行su 后的脚本</a></li>
</ul>Zhizheng Zhang今天一个同事问了我一个 linux 相关的问题,在服务器上用 root 用户执行如下命令 cd /elasticsearch/elasticsearch-2.3.2/bin && su elasticsearch && ./elasticsearch -d 好像执行./elasticsearch -d时,还是在root用户 根据他说的情况,我想到 su 是有命令参数的,根据他的命令,我修改了一下 su - elasticsearch -c "cd /elasticsearch/elasticsearch-2.3.2/bin && ./elasticsearch -d" 发给他后,他在自己的环境执行后,结果确实成功了。 参考资料 shell不能执行su 后的脚本本地调试 jekyll 主题时报 Could not open library ‘libcurl.dll’2018-01-18T04:23:01+00:002018-01-18T04:23:01+00:00https://www.izhizheng.org/post/jekyll-theme-next-libcurl<p>Windows 本地调试 jekyll-theme-next 主题时</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec jekyll server
</code></pre></div></div>
<p>报以下错误</p>
<blockquote>
<p>Dependency Error: Yikes! It looks like you don’t have jekyll-remote-theme or one of its dependencies installed. In order to use Jekyll as currently configured, you’ll need to install this gem. The full error message from Ruby is: ‘Could not open library ‘libcurl’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.dll’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.so.4’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.so.4.dll’: �Ҳ���ָ����ģ�顣 ‘ If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!</p>
</blockquote>
<p>经网上查询并亲自试验,发现有两种方法解决这个问题。</p>
<!-- more -->
<h2 id="解决方法">解决方法</h2>
<h3 id="方法一修改主题配置文件">方法一:修改主题配置文件</h3>
<h4 id="修改-gemfile">修改 Gemfile</h4>
<p>修改前内容</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org'
gem 'github-pages', group: :jekyll_plugins
#gem 'jekyll-admin', group: :jekyll_plugins
</code></pre></div></div>
<p>修改后内容</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org'
gem 'github-pages'
#gem 'jekyll-admin', group: :jekyll_plugins
</code></pre></div></div>
<h4 id="修改-_configyml">修改 _config.yml</h4>
<p>在 plugins 下添加 jekyll-paginate,修改前内容</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>plugins:
# jemoji conficts with toc in some no-ascii post
# - jemoji
- jekyll-sitemap
- jekyll-feed
</code></pre></div></div>
<p>修改后内容</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>plugins:
# jemoji conficts with toc in some no-ascii post
# - jemoji
- jekyll-sitemap
- jekyll-feed
- jekyll-paginate
</code></pre></div></div>
<h3 id="方法二在操作系统中安装-libcurldll">方法二:在操作系统中安装 libcurl.dll</h3>
<p>可以直接从网上下载 libcurl.dll 放到系统 path 下,或者下载 curl 源码自己编译。</p>
<h4 id="下载-libcurldll-二进制包">下载 libcurl.dll 二进制包</h4>
<p>打开网页 https://curl.haxx.se/gknw.net/7.40.0/dist-w64/,并选择一个包下载,如 <a href="https://curl.haxx.se/gknw.net/7.40.0/dist-w64/curl-7.40.0-ssh2-ssl-sspi-zlib-static-bin-w64.zip" target="_blank" rel="nofollow noopener noreferrer">curl-7.40.0-ssh2-ssl-sspi-zlib-static-bin-w64.zip</a>,解压后将目录中的 libcurl.dll 放到系统 path 下,如 Ruby 安装目录 bin 中。</p>
<h4 id="下载-curl-源码编译">下载 curl 源码编译</h4>
<p>打开网页 https://curl.haxx.se/download.html,并选择一个源码包下载,如 <a href="https://curl.haxx.se/download/curl-7.57.0.zip" target="_blank" rel="nofollow noopener noreferrer">curl-7.57.0.zip</a>,解压包到 C:\curl-7.57.0,在终端(CMD 或 Powershell)下,切换到本机 DevKit 目录,运行 msys.bat,此时会弹出一个 mingw 环境窗口,在 mingw 环境窗口中输入命令 <code class="language-plaintext highlighter-rouge">cd /c/curl-7.57.0/lib</code> 进入到 C:\curl-7.57.0\lib 目录,然后执行 <code class="language-plaintext highlighter-rouge">make -f Makefile.m32</code> 编译源码,编译完成后会在 lib 目录下会生成 libcurl.dll,将 libcurl.dll 放到系统 path 下,如 Ruby 安装目录 bin 中。</p>
<h2 id="方法优劣比较">方法优劣比较</h2>
<h3 id="方法一">方法一</h3>
<h4 id="优点">优点</h4>
<p>可以比较快速地进入本地调试步骤,而不用修改操作系统。</p>
<h4 id="缺点">缺点</h4>
<p>如果远方仓库(如 github)中 Gemfile 和 _config.yml plugins 部分保持主题默认的话,本地调试完成后提交时有可能误将这两部分误提交。</p>
<h3 id="方法二">方法二</h3>
<h4 id="优点-1">优点</h4>
<p>操作系统安装 libcurl.dll 后,本地 Gemfile 和 _config.yml plugins 部分可以与远方仓库(如 github)保持一致,不用做任何修改。</p>
<h4 id="缺点-1">缺点</h4>
<p>要修改操作系统,比较麻烦,还有可能给系统带来安全性的问题。</p>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://stackoverflow.com/questions/47720302/jekyll-serve-dependency-error-could-not-open-lib-curl" target="_blank" rel="nofollow noopener noreferrer">jekyll serve dependency error - Could not open ‘lib curl’</a></li>
<li><a href="https://ruby-china.org/topics/1084" target="_blank" rel="nofollow noopener noreferrer">Ruby 在 windows xp 成功编译 gem typhoeus 的步骤</a></li>
</ul>Zhizheng ZhangWindows 本地调试 jekyll-theme-next 主题时 bundle exec jekyll server 报以下错误 Dependency Error: Yikes! It looks like you don’t have jekyll-remote-theme or one of its dependencies installed. In order to use Jekyll as currently configured, you’ll need to install this gem. The full error message from Ruby is: ‘Could not open library ‘libcurl’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.dll’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.so.4’: �Ҳ���ָ����ģ�顣 . Could not open library ‘libcurl.so.4.dll’: �Ҳ���ָ����ģ�顣 ‘ If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/! 经网上查询并亲自试验,发现有两种方法解决这个问题。HttpClient 并发报 Timeout waiting for connection from pool2018-01-17T03:00:01+00:002018-01-17T03:00:01+00:00https://www.izhizheng.org/post/HttpClient-Concurrent-Timeout<p>新建了一个 HttpClient 实例,使用 for 循环调用,结果报出以下错误</p>
<blockquote>
<p>java
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool</p>
</blockquote>
<p>解决方法,修改连接池配置,增大连接数</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">RequestConfig</span> <span class="n">config</span> <span class="o">=</span> <span class="nc">RequestConfig</span><span class="o">.</span><span class="na">custom</span><span class="o">()</span>
<span class="o">.</span><span class="na">setSocketTimeout</span><span class="o">(</span><span class="n">socketTimeout</span><span class="o">)</span>
<span class="o">.</span><span class="na">setConnectTimeout</span><span class="o">(</span><span class="n">connectTimeout</span><span class="o">)</span>
<span class="o">.</span><span class="na">setConnectionRequestTimeout</span><span class="o">(</span><span class="n">connectionRequestTimeout</span><span class="o">).</span><span class="na">build</span><span class="o">();</span>
<span class="n">httpClient</span> <span class="o">=</span> <span class="nc">HttpClients</span><span class="o">.</span><span class="na">custom</span><span class="o">().</span><span class="na">setDefaultRequestConfig</span><span class="o">(</span><span class="n">config</span><span class="o">)</span>
<span class="o">.</span><span class="na">setMaxConnTotal</span><span class="o">(</span><span class="n">maxConnTotal</span><span class="o">)</span>
<span class="o">.</span><span class="na">setMaxConnPerRoute</span><span class="o">(</span><span class="n">maxConnPerRoute</span><span class="o">).</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="http://jinnianshilongnian.iteye.com/blog/2089792" target="_blank" rel="nofollow noopener noreferrer">使用httpclient必须知道的参数设置及代码写法、存在的风险</a></li>
<li><a href="http://blog.csdn.net/falynn1220/article/details/50607789" target="_blank" rel="nofollow noopener noreferrer">HttpClient大并发下Timeout waiting for connection from pool优化方案</a></li>
</ul>Zhizheng Zhang新建了一个 HttpClient 实例,使用 for 循环调用,结果报出以下错误 java org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool 解决方法,修改连接池配置,增大连接数 RequestConfig config = RequestConfig.custom() .setSocketTimeout(socketTimeout) .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout).build(); httpClient = HttpClients.custom().setDefaultRequestConfig(config) .setMaxConnTotal(maxConnTotal) .setMaxConnPerRoute(maxConnPerRoute).build(); 参考资料 使用httpclient必须知道的参数设置及代码写法、存在的风险 HttpClient大并发下Timeout waiting for connection from pool优化方案修改本站点主题为 NexT2018-01-16T10:00:01+00:002018-01-16T10:00:01+00:00https://www.izhizheng.org/post/change-site-theme-next<p>修改本站点主题为 NexT。</p>Zhizheng Zhang修改本站点主题为 NexT。