<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title><![CDATA[Zhang Teng'Blog]]></title>
  
  <link href="/atom.xml" rel="self"/>
  <link href="//"/>
  <updated>2015-05-31T06:32:06.132Z</updated>
  <id>//</id>
  
  <author>
    <name><![CDATA[Zhang Teng]]></name>
    
  </author>
  
  <generator uri="http://zespia.tw/hexo/">Hexo</generator>
  
  <entry>
    <title><![CDATA[gitlab只使用https协议]]></title>
    <link href="/2015/05/30/gitlab%E5%8F%AA%E4%BD%BF%E7%94%A8https%E5%8D%8F%E8%AE%AE/"/>
    <id>/2015/05/30/gitlab只使用https协议/</id>
    <published>2015-05-30T14:25:04.000Z</published>
    <updated>2015-05-31T06:26:20.000Z</updated>
    <content type="html"><![CDATA[<p>主要修改两个地方</p>
<a id="more"></a>

<h3 id="1_修改app/views/shared/_clone_panel-html-haml">1 修改<code>app/views/shared/_clone_panel.html.haml</code></h3>
<p>删掉下面这段代码</p>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre>%button{ |
      <span class="class"><span class="keyword">class</span>: "<span class="title">btn</span> <span class="comment">#{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }", |</span></span>
      <span class="symbol">:<span class="string">"data-clone"</span></span> =&gt; project.ssh_url_to_repo, |
      <span class="symbol">:<span class="string">"data-title"</span></span> =&gt; <span class="string">"Add an SSH key to your profile&lt;br&gt; to pull or push via SSH"</span>,
      <span class="symbol">:<span class="string">"data-html"</span></span> =&gt; <span class="string">"true"</span>,
      <span class="symbol">:<span class="string">"data-container"</span></span> =&gt; <span class="string">"body"</span>}
      <span class="constant">SSH</span>
</pre></td></tr></table></figure>

<h3 id="2_修改-/app/helpers/projects_helper-rb">2 修改<code>./app/helpers/projects_helper.rb</code></h3>
<figure class="highlight ruby"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="function"><span class="keyword">def</span> </span>default_url_to_repo(project = <span class="keyword">nil</span>)
    project = project || <span class="variable">@project</span>
    current_user ? project.http_url_to_repo <span class="symbol">:</span> project.url_to_repo
  <span class="keyword">end</span>

  <span class="function"><span class="keyword">def</span> </span>default_clone_protocol
    current_user ? <span class="string">"http"</span> <span class="symbol">:</span> <span class="string">"ssh"</span>
  <span class="keyword">end</span>
</pre></td></tr></table></figure>]]></content>
    <summary type="html"><![CDATA[<p>主要修改两个地方</p>
]]></summary>
    
      <category term="gitlab" scheme="/tags/gitlab/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[基于Docker的Hadoop完全分布式环境搭建]]></title>
    <link href="/2015/05/19/%E5%9F%BA%E4%BA%8EDocker%E7%9A%84Hadoop%E5%AE%8C%E5%85%A8%E5%88%86%E5%B8%83%E5%BC%8F%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/"/>
    <id>/2015/05/19/基于Docker的Hadoop完全分布式环境搭建/</id>
    <published>2015-05-19T15:55:37.000Z</published>
    <updated>2015-05-31T06:18:35.000Z</updated>
    <content type="html"><![CDATA[<h3 id="1_配置docker环境">1 配置docker环境</h3>
<p>创建一个带有ssh的centos的docker images，命名为centos6-ssh（建议采用centos6）并且ssh能在容器启动是自启动，不是本部分的重点，不详细描述。</p>
<h3 id="2_启动docker，配置java">2 启动docker，配置java</h3>
<a id="more"></a>

<p>2.1 启动第1步中创建的容器。</p>
<p>docker run -it centos6-ssh /bin/bash</p>
<p>2.2 安装Java</p>
<p>不是本文重点，不具体描述。Java的安装目录是<code>/opt/java8</code></p>
<h3 id="3_安装Hadoop">3 安装Hadoop</h3>
<h4 id="3-1_下载Hadoop">3.1 下载Hadoop</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>
shell&gt;&gt; cd /opt

shell&gt;&gt; wget http://mirrors<span class="preprocessor">.cnnic</span><span class="preprocessor">.cn</span>/apache/hadoop/common/hadoop-<span class="number">2.6</span><span class="number">.0</span>/hadoop-<span class="number">2.6</span><span class="number">.0</span><span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>

shell&gt;&gt; tar -zxvf hadoop-<span class="number">2.6</span><span class="number">.0</span><span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
</pre></td></tr></table></figure>

<h4 id="3-2_配置环境变量">3.2 配置环境变量</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre>
shell&gt;&gt; vim /etc/profile

<span class="comment"># 输入一下内容</span>

<span class="keyword">export</span> HADOOP_HOME=/opt/hadoop-<span class="number">2.6</span>.<span class="number">0</span>/

<span class="keyword">export</span> HADOOP_CONFIG_HOME=<span class="variable">$HADOOP_HOME</span>/etc/hadoop

<span class="keyword">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$HADOOP_HOME</span>/bin

<span class="keyword">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$HADOOP_HOME</span>/sbin
</pre></td></tr></table></figure>

<h4 id="3-3_配置Hadoop">3.3 配置Hadoop</h4>
<p>下面，我们开始修改Hadoop的配置文件。主要配置core-site.xml、hdfs-site.xml、mapred-site.xml这三个文件。</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre>
<span class="built_in">shell</span>&gt;&gt; cd $HADOOP_HOME/

<span class="built_in">shell</span>&gt;&gt; mkdir tmp

<span class="built_in">shell</span>&gt;&gt; mkdir namenode

<span class="built_in">shell</span>&gt;&gt; mkdir datanode
</pre></td></tr></table></figure>

<p>这里创建了三个目录，后续配置的时候会用到：</p>
<pre><code><span class="bullet">1. </span>tmp：作为Hadoop的临时目录

<span class="bullet">2. </span>namenode：作为NameNode的存放目录

<span class="bullet">3. </span>datanode：作为DataNode的存放目录
</code></pre><p>接下来进入配置文件夹，开始配置</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>
shell&gt;&gt; <span class="built_in">cd</span> <span class="variable">$HADOOP_CONFIG_HOME</span>/
</pre></td></tr></table></figure>

<h5 id="3-3-1_core-site-xml配置">3.3.1 core-site.xml配置</h5>
<figure class="highlight"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
</pre></td><td class="code"><pre>
<span class="pi">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>

<span class="pi">&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;</span>

<span class="comment">&lt;!--

  Licensed under the Apache License, Version 2.0 (the "License");

  you may not use this file except in compliance with the License.

  You may obtain a copy of the License at



    http://www.apache.org/licenses/LICENSE-2.0



  Unless required by applicable law or agreed to in writing, software

  distributed under the License is distributed on an "AS IS" BASIS,

  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  See the License for the specific language governing permissions and

  limitations under the License. See accompanying LICENSE file.

--&gt;</span>



<span class="comment">&lt;!-- Put site-specific property overrides in this file. --&gt;</span>



<span class="tag">&lt;<span class="title">configuration</span>&gt;</span>

    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

            <span class="tag">&lt;<span class="title">name</span>&gt;</span>hadoop.tmp.dir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

            <span class="tag">&lt;<span class="title">value</span>&gt;</span>/opt/hadoop-2.6.0/tmp<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

            <span class="tag">&lt;<span class="title">description</span>&gt;</span>A base for other temporary directories.<span class="tag">&lt;/<span class="title">description</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>



    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

            <span class="tag">&lt;<span class="title">name</span>&gt;</span>fs.default.name<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

            <span class="tag">&lt;<span class="title">value</span>&gt;</span>hdfs://master.hadoop.com:9000<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

            <span class="tag">&lt;<span class="title">final</span>&gt;</span>true<span class="tag">&lt;/<span class="title">final</span>&gt;</span>

            <span class="tag">&lt;<span class="title">description</span>&gt;</span>The name of the default file system.  A URI whose

            scheme and authority determine the FileSystem implementation.  The

            uri's scheme determines the config property (fs.SCHEME.impl) naming

            the FileSystem implementation class.  The uri's authority is used to

            determine the host, port, etc. for a filesystem.<span class="tag">&lt;/<span class="title">description</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>

<span class="tag">&lt;/<span class="title">configuration</span>&gt;</span>
</pre></td></tr></table></figure>

<p>注意：</p>
<pre><code>* hadoop<span class="preprocessor">.tmp</span><span class="preprocessor">.dir</span>配置项值即为此前命令中创建的临时目录路径。

* fs<span class="preprocessor">.default</span><span class="preprocessor">.name</span>配置为hdfs://master:<span class="number">9000</span>，指向的是一个Master节点的主机（后续我们做集群配置的时候，自然会配置这个节点，先写在这里）
</code></pre><h5 id="3-3-2_hdfs-site-xml配置">3.3.2 hdfs-site.xml配置</h5>
<figure class="highlight"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
</pre></td><td class="code"><pre>
<span class="pi">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>

<span class="pi">&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;</span>

<span class="comment">&lt;!--

  Licensed under the Apache License, Version 2.0 (the "License");

  you may not use this file except in compliance with the License.

  You may obtain a copy of the License at



    http://www.apache.org/licenses/LICENSE-2.0



  Unless required by applicable law or agreed to in writing, software

  distributed under the License is distributed on an "AS IS" BASIS,

  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  See the License for the specific language governing permissions and

  limitations under the License. See accompanying LICENSE file.

--&gt;</span>



<span class="comment">&lt;!-- Put site-specific property overrides in this file. --&gt;</span>



<span class="tag">&lt;<span class="title">configuration</span>&gt;</span>

    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

        <span class="tag">&lt;<span class="title">name</span>&gt;</span>dfs.replication<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

        <span class="tag">&lt;<span class="title">value</span>&gt;</span>2<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

        <span class="tag">&lt;<span class="title">final</span>&gt;</span>true<span class="tag">&lt;/<span class="title">final</span>&gt;</span>

        <span class="tag">&lt;<span class="title">description</span>&gt;</span>Default block replication.

        The actual number of replications can be specified when the file is created.

        The default is used if replication is not specified in create time.

        <span class="tag">&lt;/<span class="title">description</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>



    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

        <span class="tag">&lt;<span class="title">name</span>&gt;</span>dfs.namenode.name.dir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

        <span class="tag">&lt;<span class="title">value</span>&gt;</span>/opt/hadoop-2.6.0/namenode<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

        <span class="tag">&lt;<span class="title">final</span>&gt;</span>true<span class="tag">&lt;/<span class="title">final</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>



    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

        <span class="tag">&lt;<span class="title">name</span>&gt;</span>dfs.datanode.data.dir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

        <span class="tag">&lt;<span class="title">value</span>&gt;</span>/opt/hadoop-2.6.0/datanode<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

        <span class="tag">&lt;<span class="title">final</span>&gt;</span>true<span class="tag">&lt;/<span class="title">final</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>

<span class="tag">&lt;/<span class="title">configuration</span>&gt;</span>
</pre></td></tr></table></figure>

<p>注意：</p>
<ul>
<li><p>我们后续搭建集群环境时，将配置一个Master节点和两个Slave节点。所以dfs.replication配置为2。</p>
</li>
<li><p>dfs.namenode.name.dir和dfs.datanode.data.dir分别配置为之前创建的NameNode和DataNode的目录路径</p>
</li>
</ul>
<h5 id="3-3-3_mapred-site-xml配置">3.3.3 mapred-site.xml配置</h5>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>
shell&gt;&gt; <span class="keyword">cp</span> mapred-site<span class="preprocessor">.xml</span><span class="preprocessor">.template</span> mapred-site<span class="preprocessor">.xml</span>
</pre></td></tr></table></figure>

<figure class="highlight"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre>
<span class="pi">&lt;?xml version="1.0"?&gt;</span>

<span class="pi">&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;</span>

<span class="comment">&lt;!--

  Licensed under the Apache License, Version 2.0 (the "License");

  you may not use this file except in compliance with the License.

  You may obtain a copy of the License at



    http://www.apache.org/licenses/LICENSE-2.0



  Unless required by applicable law or agreed to in writing, software

  distributed under the License is distributed on an "AS IS" BASIS,

  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  See the License for the specific language governing permissions and

  limitations under the License. See accompanying LICENSE file.

--&gt;</span>



<span class="comment">&lt;!-- Put site-specific property overrides in this file. --&gt;</span>



<span class="tag">&lt;<span class="title">configuration</span>&gt;</span>

    <span class="tag">&lt;<span class="title">property</span>&gt;</span>

        <span class="tag">&lt;<span class="title">name</span>&gt;</span>mapred.job.tracker<span class="tag">&lt;/<span class="title">name</span>&gt;</span>

        <span class="tag">&lt;<span class="title">value</span>&gt;</span>master.hadoop.com:9001<span class="tag">&lt;/<span class="title">value</span>&gt;</span>

        <span class="tag">&lt;<span class="title">description</span>&gt;</span>The host and port that the MapReduce job tracker runs

        at.  If "local", then jobs are run in-process as a single map

        and reduce task.

        <span class="tag">&lt;/<span class="title">description</span>&gt;</span>

    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>

<span class="tag">&lt;/<span class="title">configuration</span>&gt;</span>
</pre></td></tr></table></figure>

<p>这里只有一个配置项<code>mapred.job.tracker</code>，我们指向master节点机器。</p>
<h5 id="3-3-3-4_修改JAVA_HOME环境变量">3.3.3.4 修改JAVA_HOME环境变量</h5>
<p>使用命令<code>vim hadoop-env.sh</code>打开配置文件，修改配置如下：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>
<span class="comment"># The java implementation to use.</span>

<span class="keyword">export</span> JAVA_HOME=/opt/java8
</pre></td></tr></table></figure>

<h4 id="4_格式化namenode">4 格式化namenode</h4>
<p>这是很重要的一步，执行命令<code>hadoop namenode -format</code></p>
<h4 id="5_配置SSH，生成访问秘钥">5 配置SSH，生成访问秘钥</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre>
<span class="built_in">shell</span>&gt;&gt; cd ~/

<span class="built_in">shell</span>&gt;&gt; ssh-keygen -t rsa -P <span class="string">''</span> -f ~/.ssh/id_rsa

<span class="built_in">shell</span>&gt;&gt; cd .ssh

<span class="built_in">shell</span>&gt;&gt; cat id_rsa.pub &gt;&gt; authorized_keys
</pre></td></tr></table></figure>

<p>注意： 这里，我的思路是直接将密钥生成后写入镜像，免得在买个容器里面再单独生成一次，还要相互拷贝公钥，比较麻烦。当然这只是学习使用，实际操作时，应该不会这么搞，因为这样所有容器的密钥都是一样的！</p>
<h4 id="6_创建Hadoop_images">6 创建Hadoop images</h4>
<figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre>
<span class="comment"># 退出docker容器</span>

<span class="built_in">shell</span>&gt;&gt; exit

<span class="comment"># commit容器</span>

<span class="built_in">shell</span>&gt;&gt; docker commit -<span class="operator">a</span> <span class="string">"zhangteng"</span> -m <span class="string">"add hadoop"</span> b7227b0d59fe02d22ad823a5c4a478ec8de3e7882488259191984995791da953 tcheung/hadoop

得到<span class="comment"># 容器的id需要替换，可以通过docker ps -a</span>
</pre></td></tr></table></figure>

<h3 id="3_Hadoop分布式集群搭建">3 Hadoop分布式集群搭建</h3>
<p>重点来了！</p>
<p>按照 hadoop 集群的基本要求,其 中一个是 master 结点,主要是用于运行 hadoop 程序中的 namenode、secondorynamenode 和 jobtracker（新版本名字变了） 任务。用外两个结点均为 slave 结点,其中一个是用于冗余目的,如果没有冗 余,就不能称之为 hadoop 了,所以模拟 hadoop 集群至少要有 3 个结点。</p>
<p>我们搭建集群环境的时候，需要指定节点的hostname，以及配置hosts。hostname可以使用docker run命令的h参数直接指定，但hosts解析有点麻烦，需要每次重启之后重新配置</p>
<h5 id="启动master容器">启动master容器</h5>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>
shell&gt;&gt; docker run -d -h master<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>  --net=none --name=master<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span> tcheung/hadoop
</pre></td></tr></table></figure>

<h5 id="启动slave1容器">启动slave1容器</h5>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>
shell&gt;&gt; docker run -d -h slave1<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>  --net=none --name=slave1<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span> tcheung/hadoop
</pre></td></tr></table></figure>

<h5 id="启动slave2容器">启动slave2容器</h5>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>
shell&gt;&gt; docker run -d -h slave2<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>  --net=none --name=slave2<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span> tcheung/hadoop
</pre></td></tr></table></figure>

<h4 id="给3个容器配置ip">给3个容器配置ip</h4>
<p>配置ip的方式有很多，如pipework（我使用的是这个），具体可以百度。</p>
<p>master    192.168.5.10</p>
<p>slave1    192.168.5.20</p>
<p>slave2 192.168.5.30</p>
<h4 id="修改3个容器的hosts">修改3个容器的hosts</h4>
<p>通过ssh分别进入3个容器，使用<code>vim /etc/hosts</code>修改各自的hosts，添加内容如下：</p>
<figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>
<span class="number">192.168</span><span class="number">.5</span><span class="number">.10</span>    master<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>

<span class="number">192.168</span><span class="number">.5</span><span class="number">.20</span>    slave1<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>

<span class="number">192.168</span><span class="number">.5</span><span class="number">.30</span>    slave2<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>
</pre></td></tr></table></figure>

<h4 id="配置slaves">配置slaves</h4>
<p>下面我们来配置哪些节点是slave。在较老的Hadoop版本中有一个masters文件和一个slaves文件，但新版本中只有slaves文件了。</p>
<p>在master节点容器中执行如下命令：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>
shell&gt;&gt; <span class="built_in">cd</span> <span class="variable">$HADOOP_CONFIG_HOME</span>/

shell&gt;&gt; vim slaves
</pre></td></tr></table></figure>

<p>将如下slave节点的hostname信息写入该文件： </p>
<figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>
slave1<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>

slave2<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>
</pre></td></tr></table></figure>

<h4 id="启动Hadoop">启动Hadoop</h4>
<p>在master节点上执行<code>start-all.sh</code>命令，启动Hadoop。</p>
<p>如果没有报错，就代表启动成功，如果有错，那就慢慢调吧。</p>
<p>在3个节点上执行jps命令，会得到类似的结果：</p>
<p>master节点</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre>
516 ResourceManager

358 SecondaryNameNode

775 Jps

169 NameNode
</pre></td></tr></table></figure>

<p>slave1节点</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>
292 Jps

52 DataNode

153 NodeManager
</pre></td></tr></table></figure>

<p>slave1节点</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>
465 Jps

52 DataNode

153 NodeManager
</pre></td></tr></table></figure>

<p>在master节点上通过命令<code>hdfs dfsadmin -report</code>查看DataNode是否正常启动。</p>
<p>也可以通过在浏览器中输入<code>http://master.hadoop.com:50070</code>查看Hadoop的运行状态。</p>
]]></content>
    <summary type="html"><![CDATA[<h3 id="1_配置docker环境">1 配置docker环境</h3>
<p>创建一个带有ssh的centos的docker images，命名为centos6-ssh（建议采用centos6）并且ssh能在容器启动是自启动，不是本部分的重点，不详细描述。</p>
<h3 id="2_启动docker，配置java">2 启动docker，配置java</h3>
]]></summary>
    
      <category term="java" scheme="/tags/java/"/>
    
      <category term="hadoop" scheme="/tags/hadoop/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[基于Docker的Hadoop完全分布式环境搭建]]></title>
    <link href="/2015/05/18/HBase%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/"/>
    <id>/2015/05/18/HBase环境搭建/</id>
    <published>2015-05-18T15:55:37.000Z</published>
    <updated>2015-05-31T06:17:38.000Z</updated>
    <content type="html"><![CDATA[<p>HBase需要在Hadoop的基础上运行，使用了Hadoop的HDFS，所有在搭建HBase之前，需要先搭建Hadoop的环境。<br>Habse的运行模式主要有两种：</p>
<ol>
<li>单机模式</li>
<li>分布式模式<br> 2.1. 伪分布式<br> 2.2. 完全分布式<br>主要介绍单击模式和完全分布式。</li>
</ol>
<a id="more"></a>

<h3 id="1_单机模式">1 单机模式</h3>
<p>单机模式的HBase使用的是本地文件系统，并没有使用HDFS，这种方式可以用于实验，官方并不建议将这种方式用到生产环境中。<br>我选择的版本是：hbase-1.0.1（此版本是一个稳定版本）。<br>下载地址：<a href="http://mirrors.cnnic.cn/apache/hbase/stable/" target="_blank" rel="external">http://mirrors.cnnic.cn/apache/hbase/stable/</a><br>现面开始安装说明：</p>
<h4 id="1-1_安装Java">1.1 安装Java</h4>
<p>不是本文重点，不做叙述。最好选择Java7或者Java8，我选择的是Java8。</p>
<h4 id="1-2_下载HBase并解压">1.2 下载HBase并解压</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="preprocessor"># 进入安装文件夹</span>
shell&gt;&gt; cd /opt
<span class="preprocessor"># 下载</span>
shell&gt;&gt; wget http://mirrors<span class="preprocessor">.cnnic</span><span class="preprocessor">.cn</span>/apache/hbase/stable/hbase-<span class="number">1.0</span><span class="number">.1</span>-bin<span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
<span class="preprocessor"># 解压</span>
shell&gt;&gt; tar -xzvf hbase-<span class="number">1.0</span><span class="number">.1</span>-bin<span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
</pre></td></tr></table></figure><br>#### 1.3 配置HBase<br>配置hbase-site.xml<br>hbase-site.xml在conf文件夹下。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre><span class="tag">&lt;<span class="title">configuration</span>&gt;</span>
  <span class="tag">&lt;<span class="title">property</span>&gt;</span>
    <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.rootdir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
    <span class="tag">&lt;<span class="title">value</span>&gt;</span>file:///data/hbase<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
  <span class="tag">&lt;/<span class="title">property</span>&gt;</span>
  <span class="tag">&lt;<span class="title">property</span>&gt;</span>
    <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.zookeeper.property.dataDir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
    <span class="tag">&lt;<span class="title">value</span>&gt;</span>/data/zookeeper<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
  <span class="tag">&lt;/<span class="title">property</span>&gt;</span>
<span class="tag">&lt;/<span class="title">configuration</span>&gt;</span>
</pre></td></tr></table></figure><br>HBase的数据目录不需要我们去手动创建，当启HBase时，HBase会自动去创建。<br>#### 1.4 启动HBase<br>通过运行<code>bin/start-hbase.sh</code>，HBase就能启动起来。在单机模式下，HBase的所有守护进程都只运行在一个JVM下。<br><br>### 2 完全分布式模式<br>使用Docker来搭建分布式环境。<br>Docker是一种虚拟化技术，可以为我们提供虚拟化环境，启动多个Docker容器，相当于启动了多个虚拟机，各容器间是相互隔离的，基本上通过网络进行通信。<br>启动了3个Centos6的Docker容器来搭建HBase环境，3个容器情况如下：<br>|节点       |hostname         |ip          |域名                              |<br>|—————-|———————————————-|———————————|———————————————|<br>|master|master.hadoop.com|192.168.5.10|master.hadoop.com|<br>|slave1|slave1.hadoop.com|192.168.5.20|slave1.hadoop.com|<br>|slave2|slave2.hadoop.com|192.168.5.30|slave1.hadoop.com|<br>#### 2.1 配置各Docker容器环境<br>##### 2.1.1 安装Java<br>##### 2.1.2 安装、配置SSH<br>在各容器中安装SSH，并生成相应的无密码登录的公钥与私钥，并叫公钥拷贝到其他容器中，确保各容器间能通过ssh无密码登录（使用公钥登录）。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; ssh-keygen -t rsa
<span class="built_in">shell</span>&gt;&gt; cat id_rsa.pub &gt;&gt; ~/.ssh/authorized_keys
</pre></td></tr></table></figure><br>##### 2.1.3 修改host<br>通过<code>vim /etc/hosts</code>修改各容器的host，在文件中添加如下内容：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="number">192.168</span><span class="number">.5</span><span class="number">.10</span>    master<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>
<span class="number">192.168</span><span class="number">.5</span><span class="number">.20</span>    slave1<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>
<span class="number">192.168</span><span class="number">.5</span><span class="number">.30</span>    slave2<span class="preprocessor">.hadoop</span><span class="preprocessor">.com</span>
</pre></td></tr></table></figure><br>#### 2.2 配置master节点<br>##### 2.2.1 进入master节点<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>ssh root<span class="variable">@192</span>.<span class="number">168.5</span>.<span class="number">10</span>
</pre></td></tr></table></figure><br>##### 2.2.2 下载HBase并解压<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="preprocessor"># 进入安装文件夹</span>
shell&gt;&gt; cd /opt
<span class="preprocessor"># 下载</span>
shell&gt;&gt; wget http://mirrors<span class="preprocessor">.cnnic</span><span class="preprocessor">.cn</span>/apache/hbase/stable/hbase-<span class="number">1.0</span><span class="number">.1</span>-bin<span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
<span class="preprocessor"># 解压</span>
shell&gt;&gt; tar -xzvf hbase-<span class="number">1.0</span><span class="number">.1</span>-bin<span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
</pre></td></tr></table></figure><br>##### 2.2.3 配置hbase-site.xml<br>hbase-site.xml在conf文件夹下。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="tag">&lt;<span class="title">configuration</span>&gt;</span>
    <span class="tag">&lt;<span class="title">property</span>&gt;</span>
      <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.cluster.distributed<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
      <span class="tag">&lt;<span class="title">value</span>&gt;</span>true<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>
    <span class="tag">&lt;<span class="title">property</span>&gt;</span>
      <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.rootdir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
      <span class="tag">&lt;<span class="title">value</span>&gt;</span>hdfs://master.hadoop/hbase<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>


    <span class="tag">&lt;<span class="title">property</span>&gt;</span>
      <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.zookeeper.quorum<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
      <span class="tag">&lt;<span class="title">value</span>&gt;</span>master.hadoop.com,slave1.hadoop.com,slave2.hadoop.com<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>
    <span class="tag">&lt;<span class="title">property</span>&gt;</span>
      <span class="tag">&lt;<span class="title">name</span>&gt;</span>hbase.zookeeper.property.dataDir<span class="tag">&lt;/<span class="title">name</span>&gt;</span>
      <span class="tag">&lt;<span class="title">value</span>&gt;</span>/opt/zookeeper<span class="tag">&lt;/<span class="title">value</span>&gt;</span>
    <span class="tag">&lt;/<span class="title">property</span>&gt;</span>
<span class="tag">&lt;/<span class="title">configuration</span>&gt;</span>
</pre></td></tr></table></figure><br>#### 2.3 配置slave1和slave2<br>在master中已经将HBase配置好了，HBase要求所有节点的安装目录和配置完全一致，所以，最简单的方式就是将master节点中的HBase复制到slave1和slave2<br>中。<br>可以通过<code>scp</code>达到这一目的。<br>在master节点中执行如下命令：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>scp /opt/hbase-<span class="number">1.0</span>.<span class="number">1</span> root<span class="variable">@192</span>.<span class="number">168.5</span>.<span class="number">20</span><span class="symbol">:/opt</span>
scp /opt/hbase-<span class="number">1.0</span>.<span class="number">1</span> root<span class="variable">@192</span>.<span class="number">168.5</span>.<span class="number">30</span><span class="symbol">:/opt</span>
</pre></td></tr></table></figure><br>#### 2.4 启动集群<br>在master节点中，执行<code>bin/start-hbase.sh</code>就可以启动集群。如果看到类似于下面的这些信息，就表示启动成功。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre>slave1<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting zookeeper, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-zookeeper</span><span class="attribute">-slave1</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
slave2<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting zookeeper, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-zookeeper</span><span class="attribute">-slave2</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
master<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting zookeeper, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-zookeeper</span><span class="attribute">-master</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
starting master, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-master</span><span class="attribute">-master</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
slave2<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting regionserver, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-regionserver</span><span class="attribute">-slave2</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
slave1<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting regionserver, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-regionserver</span><span class="attribute">-slave1</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
slave1<span class="built_in">.</span>hadoop<span class="built_in">.</span>com: starting master, logging <span class="keyword">to</span> /opt/hbase<span class="subst">-</span><span class="number">1.0</span><span class="number">.1</span>/bin<span class="subst">/</span><span class="built_in">..</span>/logs/hbase<span class="attribute">-root</span><span class="attribute">-master</span><span class="attribute">-slave1</span><span class="built_in">.</span>hadoop<span class="built_in">.</span>com<span class="built_in">.</span>out
</pre></td></tr></table></figure><br>#### 2.5 查看各节点的进程信息<br>通过<code>jps</code>查看各节点运行的Java进程，如果看到如下的进程，表示HBase启动成功。<br>master节点<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; jps
<span class="number">20355</span> Jps
<span class="number">20071</span> HQuorumPeer
<span class="number">20137</span> HMaster
</pre></td></tr></table></figure><br>slave1节点<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; jps
<span class="number">15930</span> HRegionServer
<span class="number">16194</span> Jps
<span class="number">15838</span> HQuorumPeer
</pre></td></tr></table></figure><br>slave2节点<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; jps
<span class="number">13901</span> Jps
<span class="number">13639</span> HQuorumPeer
<span class="number">13737</span> HRegionServer
</pre></td></tr></table></figure><br>#### 2.6 在浏览器中查看运行状态<br>在浏览器中输入：<a href="http://master.hadoop.com:16010，可查看HBase运行状态。" target="_blank" rel="external">http://master.hadoop.com:16010，可查看HBase运行状态。</a><br>#### 2.7 例子演示<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
</pre></td><td class="code"><pre>建立一个表scores具有两个列族grad 和courese      
<span class="built_in">create</span> <span class="string">'scores'</span>,<span class="string">'grade'</span>, <span class="string">'course'</span> 
查看当前HBase中具有哪些表      
list 
查看表的构造      
describe <span class="string">'scores'</span> 
加入一行数据,行名称为zkb 列族grad的列名为”” 值位<span class="number">5</span>      
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'zkb'</span>,<span class="string">'grade:'</span>,<span class="string">'5'</span>

给zkb这一行的数据的列族course添加一列&lt;math,<span class="number">97</span>&gt;      
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'zkb'</span>,<span class="string">'course:math'</span>,<span class="string">'97'</span>  
给zkb这一行的数据的列族course添加一列&lt;art,<span class="number">87</span>&gt;      
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'zkb'</span>,<span class="string">'course:art'</span>,<span class="string">'87'</span>  
加入一行数据,行名称为baoniu列族grad的列名为”” 值为<span class="number">4</span>      
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'baoniu'</span>,<span class="string">'grade:'</span>,<span class="string">'4'</span> 
给baoniu这一行的数据的列族course添加一列&lt;math,<span class="number">89</span>&gt;     
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'baoniu'</span>,<span class="string">'course:math'</span>,<span class="string">'89'</span>

给baoniu这一行的数据的列族course添加一列&lt;art,<span class="number">80</span>&gt;      
<span class="built_in">put</span> <span class="string">'scores'</span>,<span class="string">'baoniu'</span>,<span class="string">'course:art'</span>,<span class="string">'80'</span>  
查看scores表中zkb的相关数据      
<span class="built_in">get</span> <span class="string">'scores'</span>,<span class="string">'zkb'</span>  
查看scores表中所有数据      
scan <span class="string">'scores'</span>  
注意：scan命令可以指定startrow,stoprow来scan多个row，例如：scan <span class="string">'user_test'</span>, {COLUMNS =&gt;<span class="string">'info:username'</span>,LIMIT =&gt;<span class="number">10</span>, STARTROW =&gt; <span class="string">'test'</span>,STOPROW=&gt;<span class="string">'test2'</span>}

查看scores表中所有数据courses列族的所有数据      
scan <span class="string">'scores'</span>,{COLUMNS =&gt; <span class="string">'course'</span>}  
删除scores表      
disable <span class="string">'scores'</span>       
drop <span class="string">'scores'</span>      
注意：先要屏蔽该表，才能对该表进行删除
</pre></td></tr></table></figure>



















]]></content>
    <summary type="html"><![CDATA[<p>HBase需要在Hadoop的基础上运行，使用了Hadoop的HDFS，所有在搭建HBase之前，需要先搭建Hadoop的环境。<br>Habse的运行模式主要有两种：</p>
<ol>
<li>单机模式</li>
<li>分布式模式<br> 2.1. 伪分布式<br> 2.2. 完全分布式<br>主要介绍单击模式和完全分布式。</li>
</ol>
]]></summary>
    
      <category term="java" scheme="/tags/java/"/>
    
      <category term="hadoop" scheme="/tags/hadoop/"/>
    
      <category term="hbase" scheme="/tags/hbase/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[基于docker的gitlab搭建]]></title>
    <link href="/2015/05/03/%E5%9F%BA%E4%BA%8Edocker%E7%9A%84gitlab%E6%90%AD%E5%BB%BA/"/>
    <id>/2015/05/03/基于docker的gitlab搭建/</id>
    <published>2015-05-03T06:21:48.000Z</published>
    <updated>2015-05-31T06:23:44.000Z</updated>
    <content type="html"><![CDATA[<p>﻿﻿﻿﻿﻿﻿﻿### 一、准备docker容器环境</p>
<h4 id="1-&nbsp;下载docker_ubuntu镜像">1.&nbsp;下载docker ubuntu镜像</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; docker pull ubuntu
</pre></td></tr></table></figure><br>#### 2.&nbsp;启动ubuntu镜像并更新<br><br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; docker run -<span class="keyword">it</span> docker.io/ubuntu
<span class="comment"># 更新操作在ubuntu容器中进行</span>
<span class="built_in">shell</span>&gt;&gt; apt-<span class="built_in">get</span> -y update
</pre></td></tr></table></figure>

<a id="more"></a>

<h4 id="3-&nbsp;安装ssh">3.&nbsp;安装ssh</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; apt-<span class="built_in">get</span> install openssh-server vim
<span class="comment"># 配置ssh</span>
<span class="built_in">shell</span>&gt;&gt; vim /etc/ssh/sshd_config
<span class="comment"># 启动ssh</span>
<span class="built_in">shell</span>&gt;&gt; service ssh start
<span class="comment"># 退出容器</span>
<span class="built_in">shell</span>&gt;&gt; exit
</pre></td></tr></table></figure><br>#### 4.&nbsp;commit docker容器<br><br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>shell<span class="subst">&gt;&gt;</span> docker commit <span class="attribute">-a</span> <span class="string">"zhangteng"</span> <span class="attribute">-m</span> <span class="string">"add ssh"</span> <span class="number">876</span>f90b7a5769c04f3d9975369b3a1148e6c951d1f4f4217728b072b6ae6a50b ubuntu<span class="attribute">-ssh</span>
ps: <span class="string">"876f90b7a5769c04f3d9975369b3a1148e6c951d1f4f4217728b072b6ae6a50b"</span>为刚刚安装了ssh的ubuntu容器的id，需要替换，id可通过ps <span class="attribute">-a</span>查到
</pre></td></tr></table></figure><br>#### 5.&nbsp;build docker容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; mkdir ubuntu_ssh
<span class="built_in">shell</span>&gt;&gt; cd ubuntu_ssh
<span class="built_in">shell</span>&gt;&gt; vim Dockerfile
</pre></td></tr></table></figure><br>在Dockerfile文件中输入如下内容:<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="preprocessor"># Add ssh to ubuntu</span>
<span class="preprocessor"># author: zhangteng</span>
<span class="preprocessor"># VERSION 1.0</span>

FROM ubuntu-ssh:latest
MAINTAINER zhangteng
 
<span class="preprocessor"># change root passwd</span>
RUN echo <span class="string">'root:123456'</span> | chpasswd
 
<span class="preprocessor"># expose ssh port</span>
EXPOSE <span class="number">22</span>
 
RUN mkdir /<span class="keyword">var</span>/run/sshd                                                                                                                  
 
<span class="preprocessor"># add run.sh</span>
ADD run.sh /run.sh
RUN chmod <span class="number">755</span> /run.sh

CMD [<span class="string">"/run.sh"</span>]
</pre></td></tr></table></figure><br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; vim run.sh
</pre></td></tr></table></figure><br> 在run.sh文件中输入如下内容：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre><span class="shebang">#!/bin/bash
 </span>
<span class="comment"># start sshd, let this at last</span>
/usr/sbin/sshd -D
</pre></td></tr></table></figure><br>build容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>docker build <span class="attribute">-t</span> ubuntu<span class="attribute">-ssh</span>:v1 <span class="built_in">.</span>
</pre></td></tr></table></figure><br>#### 6.&nbsp;启动容器并进入容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>shell<span class="subst">&gt;&gt;</span> docker run <span class="attribute">-d</span> <span class="attribute">-p</span> <span class="number">49170</span>:<span class="number">22</span> <span class="subst">--</span>name<span class="subst">=</span>ubuntu<span class="attribute">-ssh</span> ubuntu<span class="attribute">-ssh</span>:v1
shell<span class="subst">&gt;&gt;</span> ssh root@<span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> <span class="attribute">-p</span> <span class="number">49170</span>
</pre></td></tr></table></figure><br>### 二、安装gtilab<br>在完成上一步，进入docker容器之后就可以开始安装gitlab了。<br>注意：以下操作都必须在<strong>docker容器</strong>中进行，不在容器中的操作会有说明，没有说明的都在容器中操作。<br>以下内容参考<a href="http://https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md" target="_blank" rel="external">gitlab官方安装说明</a>，根据我们这边要求进行了一些说明。<br>#### 1.&nbsp;Packages/Dependencies<br>1.1&nbsp;安装需要的依赖（用于编译Ruby和一些Ruby gems需要的原生依赖）<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell<span class="subst">&gt;&gt;</span> sudo apt<span class="attribute">-get</span> install <span class="attribute">-y</span> build<span class="attribute">-essential</span> zlib1g<span class="attribute">-dev</span> libyaml<span class="attribute">-dev</span> libssl<span class="attribute">-dev</span> libgdbm<span class="attribute">-dev</span> libreadline<span class="attribute">-dev</span> libncurses5<span class="attribute">-dev</span> libffi<span class="attribute">-dev</span> curl openssh<span class="attribute">-server</span> redis<span class="attribute">-server</span> checkinstall libxml2<span class="attribute">-dev</span> libxslt<span class="attribute">-dev</span> libcurl4<span class="attribute">-openssl</span><span class="attribute">-dev</span> libicu<span class="attribute">-dev</span> logrotate python<span class="attribute">-docutils</span> pkg<span class="attribute">-config</span> cmake libkrb5<span class="attribute">-dev</span> nodejs
</pre></td></tr></table></figure><br>1.2&nbsp;检查git的版本是否正确<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
</pre></td><td class="code"><pre><span class="comment"># 安装Git</span>
<span class="built_in">shell</span>&gt;&gt; sudo apt-<span class="built_in">get</span> install -y git-core

<span class="comment"># 确保Git的版本是1.7.10或者更高</span>
<span class="built_in">shell</span>&gt;&gt; git <span class="comment">--version</span>
</pre></td></tr></table></figure><br>如果git的版本太久，可以移除它并用源码安装的方式安装一个高版本。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre><span class="comment"># 移除旧版本的Git</span>
<span class="built_in">shell</span>&gt;&gt; sudo apt-<span class="built_in">get</span> remove git-core

<span class="comment"># 安装依赖</span>
<span class="built_in">shell</span>&gt;&gt; sudo apt-<span class="built_in">get</span> install -y libcurl4-openssl-dev libexpat1-dev gettext libz-dev libssl-dev build-essential

<span class="comment"># 下载源码、编译</span>
<span class="built_in">shell</span>&gt;&gt; cd /tmp
<span class="built_in">shell</span>&gt;&gt; curl -L <span class="comment">--progress https://www.kernel.org/pub/software/scm/git/git-2.1.2.tar.gz | tar xz</span>
<span class="built_in">shell</span>&gt;&gt; cd git-<span class="number">2.1</span><span class="number">.2</span>/
<span class="built_in">shell</span>&gt;&gt; ./configure
<span class="built_in">shell</span>&gt;&gt; make prefix=/usr/<span class="built_in">local</span> all

<span class="comment"># 安装到/usr/local/bin</span>
<span class="built_in">shell</span>&gt;&gt; sudo make prefix=/usr/<span class="built_in">local</span> install

<span class="comment"># When editing config/gitlab.yml (Step 5), change the git -&gt; bin_path to /usr/local/bin/git</span>
<span class="comment"># 当在第6步编辑config/gitlab.yml的时候，需要编辑bin_path=/usr/local/bin/git</span>
</pre></td></tr></table></figure><br>1.3&nbsp;安装postfix<br>做邮件服务器用，但是现在没有调通<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; sudo apt-<span class="built_in">get</span> install -y postfix
</pre></td></tr></table></figure><br>#### 2.&nbsp;安装Ruby<br>2.1&nbsp;移除旧版本的Ruby<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; sudo apt-<span class="built_in">get</span> remove ruby1<span class="number">.8</span>
</pre></td></tr></table></figure><br>2.2&nbsp;下载Ruby源码，编译并安装<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; mkdir /tmp/ruby && cd /tmp/ruby
<span class="built_in">shell</span>&gt;&gt; curl -L <span class="comment">--progress http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.6.tar.gz | tar xz</span>
<span class="built_in">shell</span>&gt;&gt; cd ruby-<span class="number">2.1</span><span class="number">.6</span>
<span class="built_in">shell</span>&gt;&gt; ./configure <span class="comment">--disable-install-rdoc</span>
<span class="built_in">shell</span>&gt;&gt; make
<span class="built_in">shell</span>&gt;&gt; sudo make install
</pre></td></tr></table></figure><br>2.3&nbsp;更改Gem源<br>由于国内网络原因（你懂的），导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。所以你会与遇到 gem install rack 或 bundle install 的时候半天没有响应，具体可以用 gem install rails -V 来查看执行过程。<br>详见<a href="http://ruby.taobao.org/" target="_blank" rel="external">http://ruby.taobao.org/</a>。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; gem sources <span class="comment">--remove https://rubygems.org/</span>
<span class="built_in">shell</span>&gt;&gt; gem sources -<span class="operator">a</span> <span class="keyword">https</span>://ruby.taobao.org/
<span class="built_in">shell</span>&gt;&gt; gem sources -l
*** CURRENT SOURCES ***

<span class="keyword">https</span>://ruby.taobao.org
<span class="comment"># 请确保只有 ruby.taobao.org</span>
</pre></td></tr></table></figure><br>2.4&nbsp;安装Bundler Gem<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="comment">shell</span>&gt;&gt; <span class="comment">sudo</span> <span class="comment">gem</span> <span class="comment">install</span> <span class="comment">bundler</span> <span class="literal">-</span><span class="literal">-</span><span class="comment">no</span><span class="literal">-</span><span class="comment">ri</span> <span class="literal">-</span><span class="literal">-</span><span class="comment">no</span><span class="literal">-</span><span class="comment">rdoc</span>
</pre></td></tr></table></figure><br>#### 3.&nbsp;添加系统用户<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="built_in">sudo</span> adduser --disabled-login --gecos <span class="string">'GitLab'</span> git
</pre></td></tr></table></figure><br>#### 4.&nbsp;安装数据库(MySql)<br>我们使用的数据库是宿主主机的数据库，这里安装只是为了用于后面安装Gem，不需要启动这个数据库。<br>数据库可以选择Mysql或者PostgreSQL，我们使用的是Mysql。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="preprocessor"># 安装Mysql</span>
sudo apt-<span class="keyword">get</span> install -y mysql-client libmysqlclient-dev

<span class="preprocessor"># Ensure you have MySQL version 5.5.14 or later</span>
mysql --version

<span class="preprocessor"># 输入mysql的密码</span>
<span class="preprocessor"># 再次输入mysql的密码</span>
</pre></td></tr></table></figure><br>安装完数据库之后，还需要在<strong>宿主主机</strong>的Mysql中创建gitlab需要用的账户和数据库。<br>以下操作在宿主主机中执行。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre><span class="preprocessor"># 登录Mysql</span>
shell&gt;&gt; mysql -h127<span class="number">.0</span><span class="number">.0</span><span class="number">.1</span> -uroot -p

<span class="preprocessor"># 输入mysql密码</span>

<span class="preprocessor"># 创建git账户</span>
mysql&gt; CREATE USER <span class="comment">'git'@'localhost' IDENTIFIED BY 'gitlab';</span>

<span class="preprocessor"># 创建Gitlab生产环境数据库</span>
mysql&gt; CREATE DATABASE <span class="keyword">IF</span> <span class="keyword">NOT</span> EXISTS `gitlabhq_production` <span class="keyword">DEFAULT</span> CHARACTER <span class="keyword">SET</span> `utf8` COLLATE `utf8_unicode_ci`;

mysql&gt; GRANT <span class="keyword">SELECT</span>, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES <span class="keyword">ON</span> `gitlabhq_production`.* <span class="keyword">TO</span> <span class="comment">'git'@'localhost';</span>

<span class="preprocessor"># 为git添加远程访问能力</span>
mysql&gt; GRANT ALL PRIVILEGES <span class="keyword">ON</span> *.* <span class="keyword">TO</span> git@<span class="string">"192.168.5.%"</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">"git"</span>; 
mysql&gt; GRANT ALL PRIVILEGES <span class="keyword">ON</span> *.* <span class="keyword">TO</span> git@<span class="string">"172.%.%.%"</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">"git"</span>; 
<span class="preprocessor"># 更改git只能在192.168.5.*这个ip段访问</span>
mysql&gt; use mysql;
mysql&gt; update user <span class="keyword">set</span> Host=<span class="string">"192.168.5.%"</span> <span class="keyword">where</span> user=<span class="string">"git"</span> <span class="keyword">and</span> Host=<span class="string">"%"</span>;
mysql&gt; flush privileges;
mysql&gt; \q;
</pre></td></tr></table></figure><br>#### 5.&nbsp;安装Redis<br>以下操作在docker容器中进行。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>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
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="built_in">sudo</span> apt-get install redis-server

<span class="comment"># 配置redis使用socket访问</span>
shell&gt;&gt; <span class="built_in">sudo</span> cp /etc/redis/redis.conf /etc/redis/redis.conf.orig

<span class="comment"># 将redis监听端口设为0，取消其对TCP请求的监听</span>
shell&gt;&gt; sed <span class="string">'s/^port .*/port 0/'</span> /etc/redis/redis.conf.orig | <span class="built_in">sudo</span> tee /etc/redis/redis.conf
<span class="built_in">echo</span> <span class="string">'unixsocket /var/run/redis/redis.sock'</span> | <span class="built_in">sudo</span> tee <span class="operator">-a</span> /etc/redis/redis.conf
<span class="built_in">echo</span> <span class="string">'unixsocketperm 770'</span> | <span class="built_in">sudo</span> tee <span class="operator">-a</span> /etc/redis/redis.conf


<span class="comment"># 创建socket需要使用的目录</span>
shell&gt;&gt; mkdir /var/run/redis
shell&gt;&gt; chown redis:redis /var/run/redis
shell&gt;&gt; chmod <span class="number">755</span> /var/run/redis
<span class="comment"># Persist the directory which contains the socket, if applicable</span>
<span class="keyword">if</span> [ <span class="operator">-d</span> /etc/tmpfiles.d ]; <span class="keyword">then</span>
  <span class="built_in">echo</span> <span class="string">'d  /var/run/redis  0755  redis  redis  10d  -'</span> | <span class="built_in">sudo</span> tee <span class="operator">-a</span> /etc/tmpfiles.d/redis.conf
<span class="keyword">fi</span>

<span class="comment"># 重启以激活修改</span>
shell&gt;&gt; <span class="built_in">sudo</span> service redis-server restart

<span class="comment"># 将git用户添加到redis组</span>
shell&gt;&gt; <span class="built_in">sudo</span> usermod <span class="operator">-a</span>G redis git
</pre></td></tr></table></figure><br>#### 6.&nbsp;安装Gitlab<br>6.1&nbsp;克隆Gitlab源码<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; cd /home/git
<span class="built_in">shell</span>&gt;&gt; sudo -u git -H git clone <span class="keyword">https</span>://gitlab.com/gitlab-org/gitlab-ce.git -b <span class="number">7</span>-<span class="number">10</span>-stable gitlab
ps: 我有下载好的，如果下载速度太慢，可以找我要，我也会传到gitlab上
</pre></td></tr></table></figure><br>6.2&nbsp;配置Gitlab<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
</pre></td><td class="code"><pre>shell&gt;&gt; cd /home/git/gitlab

<span class="preprocessor"># 复制一份gitlab的配置文件</span>
shell&gt;&gt; sudo -u git -H <span class="keyword">cp</span> config/gitlab<span class="preprocessor">.yml</span><span class="preprocessor">.example</span> config/gitlab<span class="preprocessor">.yml</span>

<span class="preprocessor"># 根据配置文件头部的说明进行修改，可以参考我修改之后的文件，在gitlab中</span>
shell&gt;&gt; sudo -u git -H vim config/gitlab<span class="preprocessor">.yml</span>
<span class="preprocessor"># 这需要修改production这一块就可以了，列出几个需要修改的关键地方</span>
<span class="label">host:</span> gitlab<span class="preprocessor">.b</span>-m<span class="preprocessor">.net</span>
<span class="label">port:</span> <span class="number">443</span>
<span class="label">https:</span> true
<span class="label">email_from:</span> gitlab@boman<span class="preprocessor">.net</span>
<span class="label">repos_path:</span> /data/gitlab-data/repositories/

<span class="preprocessor"># 确保Gitlab对log/和tmp/这两个目录有写的权限</span>
shell&gt;&gt; sudo chown -R git log/
shell&gt;&gt; sudo chown -R git tmp/
shell&gt;&gt; sudo chmod -R u+rwX,go-w log/
shell&gt;&gt; sudo chmod -R u+rwX tmp/

<span class="preprocessor"># 创建satellites文件夹</span>
shell&gt;&gt; sudo -u git -H mkdir /home/git/gitlab-satellites
shell&gt;&gt; sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites

<span class="preprocessor"># 确保Gitlab对tmp/pids/和tmp/sockets/两个目录有写权限</span>
shell&gt;&gt; sudo chmod -R u+rwX tmp/pids/
shell&gt;&gt; sudo chmod -R u+rwX tmp/sockets/

<span class="preprocessor"># 确保Gitlab对public/uploads/目录有写权限</span>
shell&gt;&gt; sudo chmod -R u+rwX  public/uploads

<span class="preprocessor"># 复制一份Unicorn配置文件</span>
shell&gt;&gt; sudo -u git -H <span class="keyword">cp</span> config/unicorn<span class="preprocessor">.rb</span><span class="preprocessor">.example</span> config/unicorn<span class="preprocessor">.rb</span>

<span class="preprocessor"># 查找cpu的核数</span>
nproc

<span class="preprocessor"># 如果你希望有一个高负荷的实例，可以开启集群模式</span>
<span class="preprocessor"># 例如. 如果内存为2GB，设置workers为3</span>
<span class="preprocessor"># workers的值至少是cpu的核数</span>
shell&gt;&gt; sudo -u git -H vim config/unicorn<span class="preprocessor">.rb</span>
列出需要修改的关键地方
worker_processes <span class="number">4</span>
listen <span class="string">"/home/git/gitlab/tmp/sockets/gitlab.socket"</span>, :backlog =&gt; <span class="number">1024</span>
listen <span class="string">"8080"</span>, :tcp_nopush =&gt; true

<span class="preprocessor"># Copy the example Rack attack config</span>
shell&gt;&gt; sudo -u git -H <span class="keyword">cp</span> config/initializers/rack_attack<span class="preprocessor">.rb</span><span class="preprocessor">.example</span> config/initializers/rack_attack<span class="preprocessor">.rb</span>

<span class="preprocessor"># Configure Git global settings for git user, useful when editing via web</span>
<span class="preprocessor"># Edit user.email according to what is set in gitlab.yml</span>
shell&gt;&gt; sudo -u git -H git config --global user<span class="preprocessor">.name</span> <span class="string">"GitLab"</span>
shell&gt;&gt; sudo -u git -H git config --global user<span class="preprocessor">.email</span> <span class="string">"gitlab@b-m.net"</span>
shell&gt;&gt; sudo -u git -H git config --global core<span class="preprocessor">.autocrlf</span> input

<span class="preprocessor"># 配置Redis连接设置</span>
shell&gt;&gt; sudo -u git -H <span class="keyword">cp</span> config/resque<span class="preprocessor">.yml</span><span class="preprocessor">.example</span> config/resque<span class="preprocessor">.yml</span>

<span class="preprocessor"># 如果没有使用默认方式安装Redis，需要修改Redis的socket path</span>
shell&gt;&gt; sudo -u git -H editor config/resque<span class="preprocessor">.yml</span>
</pre></td></tr></table></figure><br>6.3&nbsp;配置Gitlab的数据库设置<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre>shell&gt;&gt; sudo -u git <span class="keyword">cp</span> config/database<span class="preprocessor">.yml</span><span class="preprocessor">.mysql</span> config/database<span class="preprocessor">.yml</span>
shell&gt;&gt; sudo -u git -H vim config/database<span class="preprocessor">.yml</span>
只需要修改production部分即可
<span class="label">production:</span>
  adapter: mysql2
  encoding: utf8
  collation: utf8_general_ci
  reconnect: false
  database: gitlabhq_production
  pool: <span class="number">10</span>
  username: git
  password: <span class="string">"gitlab"</span>
  host: <span class="number">192.168</span><span class="number">.5</span><span class="number">.1</span>
  socket: /alidata1/data/db3306/mysql<span class="preprocessor">.sock</span>
</pre></td></tr></table></figure><br>6.4&nbsp;安装Gems<br>6.4.1&nbsp;修改Gem源<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="built_in">sudo</span> -u git -H vim Gemfile
修改第一行
<span class="comment"># source "https://rubygems.org"</span>
<span class="built_in">source</span> <span class="string">'https://ruby.taobao.org/'</span>
</pre></td></tr></table></figure><br>6.4.2&nbsp;安装<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="comment">shell</span>&gt;&gt; <span class="comment">sudo</span> <span class="literal">-</span><span class="comment">u</span> <span class="comment">git</span> <span class="literal">-</span><span class="comment">H</span> <span class="comment">bundle</span> <span class="comment">install</span> <span class="literal">-</span><span class="literal">-</span><span class="comment">deployment</span> <span class="literal">-</span><span class="literal">-</span><span class="comment">without</span> <span class="comment">development</span> <span class="comment">test</span> <span class="comment">postgres</span> <span class="comment">aws</span>
</pre></td></tr></table></figure><br>6.5&nbsp;安装Gitlab Shell<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre>shell&gt;&gt; mkdir -p /data/gitlab-data/repositories/
shell&gt;&gt; chown -R git:git /data/gitlab-data/
shell&gt;&gt; sudo -u git -H bundle exec rake gitlab:shell:install[v2<span class="number">.6</span><span class="number">.2</span>] REDIS_URL=unix:/var/run/redis/redis<span class="preprocessor">.sock</span> RAILS_ENV=production
<span class="preprocessor"># 修改配置</span>
shell&gt;&gt; sudo -u git -H vim /home/git/gitlab-shell/config<span class="preprocessor">.yml</span>
<span class="preprocessor"># 修改后的内容如下，也可参考我上传的文件</span>
<span class="label">user:</span> git
<span class="label">gitlab_url:</span> https://gitlab<span class="preprocessor">.b</span>-m<span class="preprocessor">.net</span>/
<span class="label">http_settings:</span>
  self_signed_cert: true
<span class="label">repos_path:</span> <span class="string">"/data/gitlab-data/repositories/"</span>
<span class="label">auth_file:</span> <span class="string">"/data/gitlab-data/.ssh/authorized_keys"</span>
<span class="label">redis:</span>
  bin: <span class="string">"/usr/bin/redis-cli"</span>
  namespace: resque:gitlab
  socket: <span class="string">"/var/run/redis/redis.sock"</span>
<span class="label">log_level:</span> INFO
<span class="label">audit_usernames:</span> false
</pre></td></tr></table></figure><br>6.6&nbsp;初始化数据库<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="built_in">sudo</span> -u git -H bundle <span class="keyword">exec</span> rake gitlab:setup RAILS_ENV=production
<span class="comment"># 输入"yes"去创建数据库表</span>
<span class="comment"># 初始化完成之后可以看见"Administrator account created:"</span>
</pre></td></tr></table></figure><br>可以使用下面的语句设置管理员的密码，如果不设置将使用默认密码。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="built_in">sudo</span> -u git -H bundle <span class="keyword">exec</span> rake gitlab:setup RAILS_ENV=production GITLAB_ROOT_PASSWORD=yourpassword
</pre></td></tr></table></figure><br>6.7&nbsp;安装服务脚本<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre>sudo <span class="keyword">cp</span> lib/support/init<span class="preprocessor">.d</span>/gitlab /etc/init<span class="preprocessor">.d</span>/gitlab
<span class="preprocessor"># 设置开机自启动</span>
sudo update-rc<span class="preprocessor">.d</span> gitlab defaults <span class="number">21</span>
</pre></td></tr></table></figure><br>6.8&nbsp;安装日志管理工具<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell&gt;&gt; sudo <span class="keyword">cp</span> lib/support/logrotate/gitlab /etc/logrotate<span class="preprocessor">.d</span>/gitlab
</pre></td></tr></table></figure><br>6.9&nbsp;检查程序状态<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">sudo</span> -u git -H bundle <span class="keyword">exec</span> rake gitlab:env:info RAILS_ENV=production
</pre></td></tr></table></figure><br>6.10&nbsp;预编译<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">sudo</span> -u git -H bundle <span class="keyword">exec</span> rake assets:precompile RAILS_ENV=production
</pre></td></tr></table></figure><br>6.11&nbsp;启动Gitlab<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">sudo</span> service gitlab start
</pre></td></tr></table></figure><br>7.&nbsp;退出docker容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell&gt;&gt; <span class="keyword">exit</span>;
</pre></td></tr></table></figure><br><strong>到这里，gitlab已经可以投入使用了，后面的操作只是对docker进行一些更多的操作，保存镜像，配置静态ip。</strong><br>### 三、将Gitlab容器做成docker镜像，配置静态ip<br>#### 1.&nbsp;commit docker容器<br>这里commit的是刚刚安装了Gitlab的容器。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>docker commit <span class="attribute">-a</span> <span class="string">"zhangteng"</span> <span class="attribute">-m</span><span class="string">"add gitlab"</span> <span class="number">26</span>d8f1393450e6743e2f6becfb2ca4574e04cbb101234bb95f04d157fa9af6c2 ubuntu<span class="attribute">-gitlab</span>
ps: <span class="string">"26d8f1393450e6743e2f6becfb2ca4574e04cbb101234bb95f04d157fa9af6c2"</span>为刚刚安装了Gitlab的ubuntu<span class="attribute">-ssh</span>容器的id，需要替换，id可通过ps <span class="attribute">-a</span>查到
</pre></td></tr></table></figure><br>#### 2.&nbsp;build docker容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; mkdir ubuntu_gitlab
<span class="built_in">shell</span>&gt;&gt; cd ubuntu_gitlab
<span class="built_in">shell</span>&gt;&gt; vim Dockerfile
</pre></td></tr></table></figure><br>在Dockerfile文件中输入如下内容:<br><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre><span class="preprocessor"># Add gitlab to ubuntu</span>
<span class="preprocessor"># author: zhangteng</span>
<span class="preprocessor"># VERSION 1.0</span>

FROM ubuntu-gitlab:latest
MAINTAINER zhangteng

<span class="preprocessor"># expose port 80</span>
EXPOSE <span class="number">80</span>

<span class="preprocessor"># expose port 443</span>
EXPOSE <span class="number">443</span>

<span class="preprocessor"># add run.sh</span>
ADD run.sh /run.sh
RUN chmod <span class="number">755</span> /run.sh

CMD [<span class="string">"/run.sh"</span>]
</pre></td></tr></table></figure><br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; vim run.sh
</pre></td></tr></table></figure><br>在run.sh文件中输入如下内容：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre><span class="shebang">#!/bin/bash
</span>
<span class="comment"># start redis</span>
/etc/init.d/redis-server stop &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span>
/etc/init.d/redis-server start &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span>
<span class="comment"># start gitlab</span>
/etc/init.d/gitlab stop &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span> 
/etc/init.d/gitlab start &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span>

<span class="comment"># start sshd, let this at last</span>
/usr/sbin/sshd -D &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span>
</pre></td></tr></table></figure><br>最后，build容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>docker build <span class="attribute">-t</span> ubuntu<span class="attribute">-gitlab</span>:v1 <span class="built_in">.</span>
</pre></td></tr></table></figure><br>#### 3.&nbsp;启动docker容器<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre>docker run <span class="attribute">-d</span> <span class="attribute">-v</span> /alidata1/docker<span class="attribute">-gitlab</span>:/<span class="built_in">data</span>/gitlab<span class="attribute">-data</span> <span class="subst">--</span>net<span class="subst">=</span><span class="literal">none</span> <span class="subst">--</span>name<span class="subst">=</span>gitlabv1 ubuntu<span class="attribute">-gitlab</span>:v1
<span class="attribute">-v</span>参数需要根据实际情况修改
/alidata1/docker<span class="attribute">-gitlab</span>文件夹需要先创建好
</pre></td></tr></table></figure><br>#### 4.&nbsp;为docker容器配置静态ip<br>可以使用我提供的脚本docker_static_ip.sh为docker设置静态ip<br>使用方法如下为：<code>sh  docker_static_ip.sh 容器id/容器name ip</code><br>容器id可以通过<code>docker ps</code>得到<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>sh docker_static_ip<span class="preprocessor">.sh</span> <span class="number">69</span>ead0a0e1ba266f97232f4f51940e9dd2da21952ce8517b99c699b66ad10a24 <span class="number">192.168</span><span class="number">.5</span><span class="number">.5</span>
</pre></td></tr></table></figure><br>#### 5.&nbsp;进入docker容器<br>由于第3步启动docker容器的时候，docker容器还没有ip，在第4步的时候才设置，Gitlab在启动的时候会去连接Mysql，这个时候是连不上的，所以启动不起来，需要进入手动启动<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; ssh root@<span class="number">192.168</span><span class="number">.5</span><span class="number">.5</span>
<span class="comment"># 输入docker容器的root密码</span>
<span class="built_in">shell</span>&gt;&gt; service gitlab restart
<span class="built_in">shell</span>&gt;&gt; chown -R git:git /data/gitlab-data
<span class="built_in">shell</span>&gt;&gt; exit
</pre></td></tr></table></figure><br>#### 6.&nbsp;在宿主主机中配置反向代理<br>配置反向代理到docker容器中，具体配置参考gitlab.b-m.net.conf文件。<br>我们使用的是https，但是没有证书，所以需要自己生成一个，可以用下面的命令：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell<span class="subst">&gt;&gt;</span> openssl req <span class="attribute">-newkey</span> rsa:<span class="number">2048</span> <span class="attribute">-x509</span> <span class="attribute">-nodes</span> <span class="attribute">-days</span> <span class="number">3560</span> <span class="attribute">-out</span> gitlab<span class="built_in">.</span>crt <span class="attribute">-keyout</span> gitlab<span class="built_in">.</span>key
</pre></td></tr></table></figure><br>#### 7.&nbsp;访问<br>在浏览器中输入地址访问即可<br>### 四、使用中的一些问题<br>#### 1.&nbsp;设置git忽略对https的检测<br>由于我们使用的是自签名证书，git会对https进行检测，所以需要设置git对它忽略<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>shell&gt;&gt; git config --<span class="keyword">global</span> http.sslVerify <span class="string">"false"</span>
</pre></td></tr></table></figure><br>#### 2.&nbsp;让git记住用户名和密码<br>编辑工程目录下的.git/config，在最后增加<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre><span class="title">[credential]</span>
<span class="setting">helper = <span class="value">store</span></span>
</pre></td></tr></table></figure>]]></content>
    <summary type="html"><![CDATA[<p>﻿﻿﻿﻿﻿﻿﻿### 一、准备docker容器环境</p>
<h4 id="1-&nbsp;下载docker_ubuntu镜像">1.&nbsp;下载docker ubuntu镜像</h4>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; docker pull ubuntu
</pre></td></tr></table></figure><br>#### 2.&nbsp;启动ubuntu镜像并更新<br><br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt;&gt; docker run -<span class="keyword">it</span> docker.io/ubuntu
<span class="comment"># 更新操作在ubuntu容器中进行</span>
<span class="built_in">shell</span>&gt;&gt; apt-<span class="built_in">get</span> -y update
</pre></td></tr></table></figure>

]]></summary>
    
      <category term="linux" scheme="/tags/linux/"/>
    
      <category term="docker" scheme="/tags/docker/"/>
    
      <category term="gitlab" scheme="/tags/gitlab/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[docker使用自定义网桥]]></title>
    <link href="/2015/04/24/docker%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BD%91%E6%A1%A5/"/>
    <id>/2015/04/24/docker使用自定义网桥/</id>
    <published>2015-04-24T06:19:26.000Z</published>
    <updated>2015-05-31T06:22:34.000Z</updated>
    <content type="html"><![CDATA[<p>参考网址：<a href="https://docs.docker.com/articles/networking/" target="_blank" rel="external">https://docs.docker.com/articles/networking/</a></p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>$ <span class="built_in">sudo</span> service docker stop
$ <span class="built_in">sudo</span> ip link <span class="keyword">set</span> dev docker0 down
$ <span class="built_in">sudo</span> brctl delbr docker0
$ <span class="built_in">sudo</span> iptables -t nat -F POSTROUTING
</pre></td></tr></table></figure>

<a id="more"></a>

<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre># <span class="operator"><span class="keyword">Create</span> our own bridge

$ sudo brctl addbr docker-bridge
$ sudo ip addr <span class="keyword">add</span> <span class="number">192.168</span><span class="number">.5</span><span class="number">.1</span>/<span class="number">24</span> dev docker-bridge
$ sudo ip link <span class="keyword">set</span> dev docker-bridge up

# Confirming that our bridge <span class="keyword">is</span> up <span class="keyword">and</span> running

$ ip addr <span class="keyword">show</span> docker-bridge
<span class="number">4</span>: docker-bridge: &lt;BROADCAST,MULTICAST&gt; mtu <span class="number">1500</span> qdisc noop state UP <span class="keyword">group</span> <span class="keyword">default</span>
    link/ether <span class="number">66</span>:<span class="number">38</span>:d0:<span class="number">0</span>d:<span class="number">76</span>:<span class="number">18</span> brd ff:ff:ff:ff:ff:ff
    inet <span class="number">192.168</span><span class="number">.5</span><span class="number">.1</span>/<span class="number">24</span> scope <span class="keyword">global</span> docker-bridge
       valid_lft forever preferred_lft forever

# Tell Docker about it <span class="keyword">and</span> restart (<span class="keyword">on</span> Ubuntu)

$ echo <span class="string">'DOCKER_OPTS="-b=docker-bridge"'</span> &gt;&gt; /etc/<span class="keyword">default</span>/docker
$ sudo service docker <span class="keyword">start</span>

# Confirming new outgoing NAT masquerade <span class="keyword">is</span> <span class="keyword">set</span> up

$ sudo iptables -t nat -L -n</span>
</pre></td></tr></table></figure>]]></content>
    <summary type="html"><![CDATA[<p>参考网址：<a href="https://docs.docker.com/articles/networking/" target="_blank" rel="external">https://docs.docker.com/articles/networking/</a></p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>$ <span class="built_in">sudo</span> service docker stop
$ <span class="built_in">sudo</span> ip link <span class="keyword">set</span> dev docker0 down
$ <span class="built_in">sudo</span> brctl delbr docker0
$ <span class="built_in">sudo</span> iptables -t nat -F POSTROUTING
</pre></td></tr></table></figure>

]]></summary>
    
      <category term="linux" scheme="/tags/linux/"/>
    
      <category term="docker" scheme="/tags/docker/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[常见的负载均衡的方式]]></title>
    <link href="/2015/04/10/%E5%B8%B8%E8%A7%81%E7%9A%84%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%9A%84%E6%96%B9%E5%BC%8F/"/>
    <id>/2015/04/10/常见的负载均衡的方式/</id>
    <published>2015-04-10T06:29:55.000Z</published>
    <updated>2015-05-31T06:31:34.000Z</updated>
    <content type="html"><![CDATA[<h2 id="1_负载均衡">1 负载均衡</h2>
<h3 id="1-1_场景引入">1.1 场景引入</h3>
<p>Tomcat最大能承受的访问量是300，现在需要处理同时并发1000的访问量，应该怎么做？</p>
<h3 id="1-2_负载均衡的概念">1.2 负载均衡的概念</h3>
<p>百度百科的解释。<br>负载均衡 建立在现有网络结构之上，它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。<br>负载均衡，英文名称为Load Balance，其意思就是分摊到多个操作单元上进行执行，例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等，从而共同完成工作任务。</p>
<a id="more"></a>

<h2 id="2_常见的负载均衡的方式">2 常见的负载均衡的方式</h2>
<h3 id="2-1_基于DNS">2.1 基于DNS</h3>
<p>在DNS上做负载均衡。</p>
<h3 id="2-2_基于反向代理服务器（Apache、Nginx）">2.2 基于反向代理服务器（Apache、Nginx）</h3>
<p>正向代理和反向代理的区别。<br>Nginx的配置如下：</p>
<p><figure class="highlight"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
</pre></td><td class="code"><pre>upstream pandawork {
    server <span class="number">192.168</span>.<span class="number">1.25</span>;
    server <span class="number">192.168</span>.<span class="number">1.30</span>;
}
server {
    listen       <span class="number">80</span>;
    server_name  www.pandawork.net;

    location / {
        proxy_<span class="keyword">set</span>_header   Host             <span class="variable">$host</span>;
        proxy_<span class="keyword">set</span>_header   X-Real-IP        <span class="variable">$remote_addr</span>;
        proxy_<span class="keyword">set</span>_header  X-Forwarded-For  <span class="variable">$proxy_add_x_forwarded_for</span>;
        client_max_body_size       <span class="number">12</span>m;
        client_body_buffer_size    <span class="number">128</span>k;
        client_body_temp_path      data/client_body_temp;
        proxy_connect_timeout      <span class="number">90</span>;
        proxy_send_timeout         <span class="number">90</span>;
        proxy_<span class="built_in">read</span>_timeout         <span class="number">90</span>;
        proxy_buffer_size          <span class="number">4</span>k;
        proxy_buffers              <span class="number">4</span> <span class="number">32</span>k;
        proxy_busy_buffers_size    <span class="number">64</span>k;
        proxy_temp_file_write_size <span class="number">64</span>k;
        proxy_temp_path            data/proxy_temp;

        proxy_pass http://pandawork;
    }
}
<span class="number">5</span>种方式的分配:
<span class="number">1</span>、轮询（默认）
每个请求按时间顺序逐一分配到不同的后端服务器，如果后端服务器down掉，能自动剔除。
upstream pandawork {
    server <span class="number">192.168</span>.<span class="number">1.25</span>;
    server <span class="number">192.168</span>.<span class="number">1.30</span>;
}

<span class="number">2</span>、weight
指定轮询几率，weight和访问比率成正比，用于后端服务器性能不均的情况。
upstream pandawork {
    server <span class="number">192.168</span>.<span class="number">1.25</span> weight=<span class="number">10</span>;
    server <span class="number">192.168</span>.<span class="number">1.30</span> weight=<span class="number">10</span>;
}

<span class="number">3</span>、ip_<span class="built_in">hash</span>
每个请求按访问ip的<span class="built_in">hash</span>结果分配，这样每个访客固定访问一个后端服务器，可以解决session的问题。
upstream pandawork {
    ip_<span class="built_in">hash</span>;
    server <span class="number">192.168</span>.<span class="number">1.25</span>
    server <span class="number">192.168</span>.<span class="number">1.30</span>;
}

<span class="number">4</span>、fair（第三方）
按后端服务器的响应时间来分配请求，响应时间短的优先分配。
upstream pandawork {
    server <span class="number">192.168</span>.<span class="number">1.25</span>;
    server <span class="number">192.168</span>.<span class="number">1.30</span>;
    fair;
}

<span class="number">5</span>、url_<span class="built_in">hash</span>（第三方）
按访问url的<span class="built_in">hash</span>结果来分配请求，使每个url定向到同一个后端服务器，后端服务器为缓存时比较有效。
upstream pandawork {
    server <span class="number">192.168</span>.<span class="number">1.25</span>;
    server <span class="number">192.168</span>.<span class="number">1.30</span>;
    <span class="built_in">hash</span> <span class="variable">$request_uri</span>;
    <span class="built_in">hash</span>_method crc32;
}
</pre></td></tr></table></figure></p>
<h3 id="2-3_基于NAT">2.3 基于NAT</h3>
<p>NAT（Network Address Translation 网络地址转换）简单地说就是将一个IP地址转换为另一个IP地址，一般用于未经注册的内部地址与合法的、已获注册的Internet IP地址间进行转换。适用于解决Internet IP地址紧张、不想让网络外部知道内部网络结构等的场合下。每次NAT转换势必会增加NAT设备的开销，但这种额外的开销对于大多数网络来说都是微不足道的，除非在高带宽有大量NAT请求的网络上。  NAT负载均衡将一个外部IP地址映射为多个内部IP地址，对每次连接请求动态地转换为一个内部服务器的地址，将外部连接请求引到转换得到地址的那个服务器上，从而达到负载均衡的目的。<br>NAT负载均衡是一种比较完善的负载均衡技术，起着NAT负载均衡功能的设备一般处于内部服务器到外部网间的网关位置，如<code>路由器、防火墙、四层交换机、专用负载均衡器</code>等，均衡算法也较灵活，如随机选择、最少连接数及响应时间等来分配负载。<br>NAT负载均衡可以通过软硬件方式来实现。软件的方式如Linux的iptables就可以实现。硬件方式就是集成了NAT服务的硬件，通常这样的硬件设备是第四层交换机和专用负载均衡器，第四层交换机的一项重要功能就是NAT负载均衡。<br>由于NAT是在第四层上做负载均衡，因此可用于出web外的多种服务，如ftp。</p>
<h3 id="2-4_基于LVS">2.4 基于LVS</h3>
<p>LVS是Linux Virtual Server的简写，意即Linux虚拟服务器，是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立，是中国国内最早出现的自由软件项目之一。<br>三种转发机制：<br>1 Virtual Server via NAT<br>2 Virtual Server via IP Tunneling<br>Virtual Server和响应服务器间建立IP隧道，响应服务器可以在远端，响应直接由响应服务器返回给客户端。<br>3 Virtual Server via Direct Routing<br>Virtual Server直接将请求转发给响应服务器，响应服务器和Virtual Server必须在一个物理局域网内，响应直接由响应服务器返回给客户端。<br>参考：<a href="http://www.360doc.com/content/12/1117/19/820209_248441825.shtml" target="_blank" rel="external">http://www.360doc.com/content/12/1117/19/820209_248441825.shtml</a></p>
<h3 id="2-5_基于NLB">2.5 基于NLB</h3>
<p>NLB(Network Load Balancing),网络负载平衡。<br>特点：<br>（1）NLB集群可以将两台或更多服务器结合起来使用<br>（2）一个NLB集群最多支持32台计算机<br>（3）NLB集群只能用于各节点的服务与数据完全相同的情况<br>（4）增强 Web、FTP、VPN等服务的可靠性和可伸缩性<br>NLB的工作原理<br>（1）集群中的每台服务器都有固定IP地址<br>（2）集群中的每台服务器还有一个共同的IP地址—NLB的集群IP地址<br>（3）NLB将客户端的访问信息发送给群集中的所有节点<br>（4）NLB算法决定提供服务的节点—其他不提供服务的节点丢弃访问请求<br>（4）NLB通过单播或多播来确保算法的特点</p>
<h3 id="2-6_基于硬件">2.6 基于硬件</h3>
<p>比较流行的是F5，价格相当高，最便宜的也要10几万。<br><a href="http://network.51cto.com/art/201004/196752.htm" target="_blank" rel="external">http://network.51cto.com/art/201004/196752.htm</a><br><a href="http://network.51cto.com/art/201004/196752.htm" target="_blank" rel="external">http://network.51cto.com/art/201004/196752.htm</a></p>
]]></content>
    <summary type="html"><![CDATA[<h2 id="1_负载均衡">1 负载均衡</h2>
<h3 id="1-1_场景引入">1.1 场景引入</h3>
<p>Tomcat最大能承受的访问量是300，现在需要处理同时并发1000的访问量，应该怎么做？</p>
<h3 id="1-2_负载均衡的概念">1.2 负载均衡的概念</h3>
<p>百度百科的解释。<br>负载均衡 建立在现有网络结构之上，它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。<br>负载均衡，英文名称为Load Balance，其意思就是分摊到多个操作单元上进行执行，例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等，从而共同完成工作任务。</p>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[Leetcode-MinStack]]></title>
    <link href="/2014/11/14/2014-11-13-MinStack/"/>
    <id>/2014/11/14/2014-11-13-MinStack/</id>
    <published>2014-11-14T15:55:37.000Z</published>
    <updated>2014-11-15T03:32:56.000Z</updated>
    <content type="html"><![CDATA[<p>先给出题目的地址吧:<a href="https://oj.leetcode.com/problems/min-stack/" target="_blank" rel="external">https://oj.leetcode.com/problems/min-stack/</a></p>
<a id="more"></a>

<p>昨天一个同学问了我这道题，回去就做了一下。<br>初看这道题，好像并不难，push、pop、top都是栈的基本操作，getMin好像不太好搞。<br>首先想到的是用一个变量min记录一下栈的最小值，每次压栈的时候比较压栈元素和min的大小，更新min值。<br>这个想法好像还不错，于是搞之，一交WA了。<br>仔细一想，如果当前的min值是栈顶的值，把栈顶的值pop之后，这个min值就不再是栈中最小的值了，此时最小值变成了栈中的次小值了。<br>自然就想到，能不能再记住次小值呢？当然是可以的。可是这样问题又来了，如果次小值再被弹出呢？那就不行了。<br>最后，想到的做法是，每次压栈的时候都去记住当前栈的最小值，把它记在栈顶上，这样栈顶就始终保存这当前栈的最小值。<br>于是，开开心心的去写代码，交之，TMD，居然告诉我MLE。<br>你大爷啊，这让我如何是好？<br>看了半天代码，实在没有内存需要优化的地方了。最后在内部类前面加了个<code>static</code>，然后就过了。<br>他就这么过了，加了个<code>static</code>为啥就过了呢？有点疑惑。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code"><pre><span class="keyword">package</span> com.tcheung;

<span class="keyword">import</span> java.util.Stack;

<span class="javadoc">/**
 * MinStack
 *
 *<span class="javadoctag"> @author</span>: zhangteng
 *<span class="javadoctag"> @time</span>: 2014/11/14 21:12
 */</span>
class MinStack {

    <span class="keyword">static</span> class Element {
        <span class="keyword">int</span> val, min;
        <span class="keyword">public</span> <span class="title">Element</span>(<span class="keyword">int</span> val, <span class="keyword">int</span> min) {
            <span class="keyword">this</span>.val = val;
            <span class="keyword">this</span>.min = min;
        }
    }

    <span class="keyword">private</span> <span class="keyword">int</span> min;

    <span class="keyword">private</span> Stack&lt;Element&gt; stack = <span class="keyword">new</span> Stack&lt;Element&gt;();

    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">push</span>(<span class="keyword">int</span> x) {
        <span class="keyword">if</span> (stack.isEmpty()) {
            min = x;
        } <span class="keyword">else</span> {
            min = Math.min(stack.peek().min, x);
        }
        stack.push(<span class="keyword">new</span> Element(x, min));
    }

    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pop</span>() {
        stack.pop();
    }

    <span class="keyword">public</span> <span class="keyword">int</span> <span class="title">top</span>() {
        <span class="keyword">return</span> stack.peek().val;
    }

    <span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getMin</span>() {
        <span class="keyword">return</span> stack.peek().min;
    }
}
</pre></td></tr></table></figure>
]]></content>
    <summary type="html"><![CDATA[<p>先给出题目的地址吧:<a href="https://oj.leetcode.com/problems/min-stack/" target="_blank" rel="external">https://oj.leetcode.com/problems/min-stack/</a></p>
]]></summary>
    
      <category term="leetcode" scheme="/tags/leetcode/"/>
    
      <category term="java" scheme="/tags/java/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[CentOS安装多个Mysql]]></title>
    <link href="/2014/11/07/2014-11-07-cetos-install-muti-mysql/"/>
    <id>/2014/11/07/2014-11-07-cetos-install-muti-mysql/</id>
    <published>2014-11-07T12:57:05.000Z</published>
    <updated>2014-11-15T05:39:19.000Z</updated>
    <content type="html"><![CDATA[<p>安装的mysql占用端口分别为3306和3307</p>
<p>下载mysql-5.6.20-linux-glibc2.5-x86_64.tar.gz，这个是编译完的二进制包</p>
<p>可阅读文件夹下的INSTALL-BINARY进行安装</p>
<a id="more"></a>

<p>两个mysql都安装在opt下面</p>
<p>3306安装命令如下</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>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
27
28
29
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt; groupadd mysql

<span class="built_in">shell</span>&gt; useradd -r -g mysql mysql

<span class="built_in">shell</span>&gt; cd /opt

<span class="built_in">shell</span>&gt; tar zxvf mysql-<span class="number">5.6</span><span class="number">.20</span>-linux-glibc2<span class="number">.5</span>-x86_64.tar.gz

<span class="built_in">shell</span>&gt; mv mysql-<span class="number">5.6</span><span class="number">.20</span>-linux-glibc2<span class="number">.5</span>-x86_64 mysql3306

<span class="built_in">shell</span>&gt; cd mysql3306

<span class="built_in">shell</span>&gt; mkdir <span class="built_in">log</span>

<span class="built_in">shell</span>&gt; mkdir tmp

<span class="built_in">shell</span>&gt; chown -R mysql .

<span class="built_in">shell</span>&gt; chgrp -R mysql .

<span class="built_in">shell</span>&gt; scripts/mysql_install_db <span class="comment">--user=mysql</span>

<span class="built_in">shell</span>&gt; chown -R root .

<span class="built_in">shell</span>&gt; chown -R mysql data

<span class="built_in">shell</span>&gt; cp support-<span class="built_in">files</span>/my-default.cnf my.cnf

<span class="built_in">shell</span>&gt; cp support-<span class="built_in">files</span>/mysql.server /etc/init.d/mysqld3306
</pre></td></tr></table></figure><br>修改my.cnf,内容如下<br><figure class="highlight"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre><span class="preprocessor"># For advice on how to change settings please see</span>
<span class="preprocessor"># http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html</span>
<span class="preprocessor"># *** DO NOT EDIT THIS FILE. It's a template which will be copied to the</span>
<span class="preprocessor"># *** default location during install, and will be replaced if you</span>
<span class="preprocessor"># *** upgrade to a newer version of MySQL.</span>

[mysqld]

<span class="preprocessor"># Remove leading # and set to the amount of RAM for the most important data</span>
<span class="preprocessor"># cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.</span>
<span class="preprocessor"># innodb_buffer_pool_size = 128M</span>

<span class="preprocessor"># Remove leading # to turn on a very important data integrity option: logging</span>
<span class="preprocessor"># changes to the binary log between backups.</span>
<span class="preprocessor"># log_bin</span>

<span class="preprocessor"># These are commonly set, remove the # and set as required.</span>
 basedir = /opt/mysql3306 
 datadir = /opt/mysql3306/data 
 port = <span class="number">3306</span> 
<span class="preprocessor"># server_id = </span>
 socket = /tmp/mysql3306.sock
 pid-file=/opt/mysql3306/tmp/mysql.pid

<span class="preprocessor"># Remove leading # to set options mainly useful for reporting servers.</span>
<span class="preprocessor"># The server defaults are faster for transactions and fast SELECTs.</span>
<span class="preprocessor"># Adjust sizes as needed, experiment to find the optimal values.</span>
<span class="preprocessor"># join_buffer_size = 128M</span>
<span class="preprocessor"># sort_buffer_size = 2M</span>
<span class="preprocessor"># read_rnd_buffer_size = 2M </span>

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

<span class="preprocessor">#log</span>
log-error=/opt/mysql3306/log/error.log
general_log=ON
general_log_file=/opt/mysql3306/log/mysql.log
long_query_time=<span class="number">2</span>
<span class="preprocessor">#log-show-queries=/opt/mysql3306/log/showquery.log</span>
log-bin=/opt/mysql3306/log/bin.log
expire_logs_days=<span class="number">15</span>
sync_binlog=<span class="number">1</span>
<span class="preprocessor">#max_binlog_cache_size = 4294967295</span>
local-infile=<span class="number">0</span>
[mysqld_safe]
log-error=/opt/mysql3306/mysqld3306.log
pid-file=/opt/mysql3306/mysqld.pid
</pre></td></tr></table></figure><br>修改/etc/init.d/mysqld3306<br>主要修改如下<br><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre>basedir=/opt/mysql3306
datadir=/opt/mysql3306/data
conf=/opt/mysql3306/my.cnf

<span class="keyword">...</span>

$bindir/mysqld_safe --defaults-file=$conf --datadir=<span class="string">"$datadir"</span> --pid-file=<span class="string">"$mysqld_pid_file_path"</span> $other_args &gt;/dev/null <span class="number">2</span>&gt;&<span class="number">1</span> &
      wait_for_pid created <span class="string">"$!"</span> <span class="string">"$mysqld_pid_file_path"</span>; return_value=$?
</pre></td></tr></table></figure>

<p>3307安装步骤如下</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt; tar zxvf mysql-<span class="number">5.6</span><span class="number">.20</span>-linux-glibc2<span class="number">.5</span>-x86_64.tar.gz

<span class="built_in">shell</span>&gt; mv mysql-<span class="number">5.6</span><span class="number">.20</span>-linux-glibc2<span class="number">.5</span>-x86_64 mysql3307

<span class="built_in">shell</span>&gt; cd mysql3307

<span class="built_in">shell</span>&gt; mkdir <span class="built_in">log</span>

<span class="built_in">shell</span>&gt; mkdir tmp

<span class="built_in">shell</span>&gt; chown -R mysql .

<span class="built_in">shell</span>&gt; chgrp -R mysql .

<span class="built_in">shell</span>&gt; scripts/mysql_install_db <span class="comment">--basedir=/opt/mysql2012 --datadur=/opt/mysql2012 --user=mysql</span>

<span class="built_in">shell</span>&gt; chown -R root .

<span class="built_in">shell</span>&gt; chown -R mysql data

<span class="built_in">shell</span>&gt; cp support-<span class="built_in">files</span>/my-default.cnf my.cnf

<span class="built_in">shell</span>&gt; cp support-<span class="built_in">files</span>/mysql.server /etc/init.d/mysqld3307
</pre></td></tr></table></figure><br>修改my.cnf和/etc/init.d/mysqld3307,修改方式与3306的一样,只是将其中的3306改成3307即可。<br><br>最后，启动mysql<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt; service mysqld3306 start
<span class="built_in">shell</span>&gt; service mysqld3307 start
看见SUCCESS就成功了
</pre></td></tr></table></figure>

<p>开机自启动</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre><span class="built_in">shell</span>&gt; chkconfig <span class="comment">--add mysqld3306</span>
<span class="built_in">shell</span>&gt; chkconfig <span class="comment">--add mysqld3307</span>
</pre></td></tr></table></figure>
]]></content>
    <summary type="html"><![CDATA[<p>安装的mysql占用端口分别为3306和3307</p>
<p>下载mysql-5.6.20-linux-glibc2.5-x86_64.tar.gz，这个是编译完的二进制包</p>
<p>可阅读文件夹下的INSTALL-BINARY进行安装</p>
]]></summary>
    
      <category term="centos" scheme="/tags/centos/"/>
    
      <category term="mysql" scheme="/tags/mysql/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[Windows下安装Redmine]]></title>
    <link href="/2014/09/09/2014-09-09-windows-install-redmine/"/>
    <id>/2014/09/09/2014-09-09-windows-install-redmine/</id>
    <published>2014-09-09T06:39:16.000Z</published>
    <updated>2014-11-15T05:36:27.000Z</updated>
    <content type="html"><![CDATA[<h3 id="准备工作">准备工作</h3>
<p>Redmine官网:<a href="http://www.redmine.org/" target="_blank" rel="external">http://www.redmine.org/</a><br>Ruby官网:<a href="http://rubyforge.org/" target="_blank" rel="external">http://rubyforge.org/</a></p>
<ol>
<li>下载railsinstaller-2.2.3.exe<br> 这是Ruby环境的一键安装包，安装上它就可以安装上全部的Ruby环境。<br> 官网:<a href="http://railsinstaller.org/en" target="_blank" rel="external">http://railsinstaller.org/en</a><br> 此安装包包含如下内容：<br> Ruby 1.9.3<br>Rails 3.2<br>Bundler<br>Git<br>Sqlite<br>TinyTDS<br>SQL Server Support<br>DevKit</li>
</ol>
<a id="more"></a>

<ol>
<li><p>下载ImageMagick，这个是图型生成工具，redmine用于生成pdf等内容，也可以不安装。安装说明在这里<br>我下载的是ImageMagick-6.8.4-0-Q16-x86-dll.exe<br>下载地址:<a href="http://download.csdn.net/detail/lqt0307/5184966" target="_blank" rel="external">http://download.csdn.net/detail/lqt0307/5184966</a><br>ps:我只找到了这个下载地址，需要1分，没有分的可以找我要。</p>
</li>
<li><p>redmine<br>这个就不用说了，上官网下就行，我用的版本是2.5.2。</p>
</li>
<li><p>mysql<br>redmine使用的数据库是mysql，所以需要安装mysql。</p>
</li>
</ol>
<h3 id="安装">安装</h3>
<ol>
<li><p>安装railsinstaller<br> 如果不选择安装目录什么的，直接下一步就可以了。</p>
</li>
<li><p>解压redmine-2.5.2.zip</p>
</li>
<li><p>安装mysql<br> 这个就不多说了。</p>
</li>
<li><p>安装mysql2插件<br> 进入Railsinstaller安装目录下的DevKit，运行DevKit目录下的msys.bat<br> 输入:<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>gem install mysql2 <span class="attribute">-v</span><span class="subst">=</span><span class="number">0.3</span><span class="number">.16</span> <span class="subst">--</span> <span class="subst">--</span><span class="keyword">with</span><span class="attribute">-mysql</span><span class="attribute">-dir</span><span class="subst">=</span><span class="string">"mysql安装目录"</span>
</pre></td></tr></table></figure><br>命令中的”mysql安装目录”要替换掉，要不要引号都可以</p>
</li>
<li><p>安装rmagick<br> window下安装rmagick，需要手动安装，不能通过：gem install rmagick 进行安装。<br> 首先需要安装ImageMagick。安装方式可以参考<a href="http://www.redmine.org/projects/redmine/wiki/HowTo_install_rmagick_gem_on_Windows" target="_blank" rel="external">http://www.redmine.org/projects/redmine/wiki/HowTo_install_rmagick_gem_on_Windows</a>，上面讲得很详细。<br> 主要也是下一步、下一步就可以了，需要注意一下的是安装目录中最好不要有空格，我在这个地方被坑了好几次。</p>
<p> 安装完ImageMagick之后，就可以安装rmagick了。进入Railsinstaller安装目录下的DevKit，运行DevKit目录下的msys.bat。<br> 输入:<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>gem install <span class="subst">--</span> <span class="subst">--</span><span class="keyword">with</span><span class="attribute">-opt</span><span class="attribute">-lib</span><span class="subst">=</span><span class="string">"ImageMagick安装目录/lib"</span>  <span class="subst">--</span><span class="keyword">with</span><span class="attribute">-opt</span><span class="attribute">-include</span><span class="subst">=</span><span class="string">"
ImageMagick安装目录/include"</span>
</pre></td></tr></table></figure><br>命令中的”ImageMagick安装目录”要替换掉，要不要引号都可以。</p>
</li>
<li><p>数据库准备<br> 6.1. 把libmysql.dll复制到“RailsInstaller安装目录\Ruby1.9.3\bin”下面。<br> 6.2. 创建数据库</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="operator"><span class="keyword">CREATE</span> <span class="keyword">DATABASE</span> db_redmine <span class="keyword">CHARACTER</span> <span class="keyword">SET</span> utf8;</span>
</pre></td></tr></table></figure>

<p> 6.3. 修改redmine连接数据库文件<br> redmine目录下的config/database.yml.example 改为config/database.yml<br> 第6行开始</p>
<figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="label">production:</span>
<span class="label">adapter:</span> mysql2
<span class="label">database:</span> redmine
<span class="label">host:</span> localhost
<span class="label">username:</span> root
<span class="label">password:</span> my_password
</pre></td></tr></table></figure>
</li>
<li><p>目录下执行:</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>bundle <span class="keyword">install</span>
</pre></td></tr></table></figure>
</li>
<li><p>初始化Redmine数据库环境</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>bundle <span class="keyword">exec</span> rake db:migrate RAILS_ENV=production
</pre></td></tr></table></figure>
</li>
<li><p>生成session存储密钥</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>bundle <span class="keyword">exec</span> rake generate_secret_token
</pre></td></tr></table></figure>
</li>
<li><p>启动Redmine</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>ruby script/rails server webrick <span class="operator">-e</span> production
</pre></td></tr></table></figure>

</li>
</ol>
<h3 id="将Redmine安装为Windows服务，开机自动运行">将Redmine安装为Windows服务，开机自动运行</h3>
<p>每次都用命令去启动Redmine还是很麻烦的，把Redmine安装成windows服务，让它能够开机自启动，还是很方便的。<br>Ruby提供一个安装Ruby程序为服务的包：mongrel_service。安装其实很简单，只要命令行下运行gem：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>gem <span class="keyword">install</span> mongrel_service
</pre></td></tr></table></figure><br>过程中安装一些必须的其他包。<br>然后将RedMine使用mongrel_service安装成Windows服务：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>mongrel_rails service<span class="tag">::install</span> <span class="attribute">-N</span> Redmine <span class="attribute">-c</span> D:<span class="subst">\</span>WebRoot <span class="attribute">-p</span> <span class="number">3000</span> <span class="attribute">-e</span> production
</pre></td></tr></table></figure><br>这里，我指定服务名为RedMine，我的Redmine在D:\WebRoot，你的要修改，注意指向Redmine的根目录。监听3000端口。<br>然后修改启动方式为自动启动，并添加MySQL服务为其依赖服务（如果你的MySQL服务器不是本机就不用麻烦了）：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="attribute">sc config Redmine start</span>=<span class="string"> auto depend= MySQL</span>
</pre></td></tr></table></figure><br>注意，执行sc config系列指令，服务必须是未启动的才行，否则会出错。<br>将来如果想去掉这个服务，只要执行：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>mongrel_rails service<span class="tag">::remove</span> <span class="attribute">-N</span> Redmine
</pre></td></tr></table></figure><br>也可以使用：<code>sc delete Redmine</code> 删除服务。<br><br>以上方式只适用于xp及xp以上系统，如果你的系统是server 2003，需要用下面这种方式：<a href="http://www.redmine.org/boards/1/topics/4123" target="_blank" rel="external">http://www.redmine.org/boards/1/topics/4123</a>。<br>上面说得很详细了，我就不在累述。<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="attribute">rake redmine:plugins:migrate RAILS_ENV</span>=<span class="string">production</span>
</pre></td></tr></table></figure>
]]></content>
    <summary type="html"><![CDATA[<h3 id="准备工作">准备工作</h3>
<p>Redmine官网:<a href="http://www.redmine.org/" target="_blank" rel="external">http://www.redmine.org/</a><br>Ruby官网:<a href="http://rubyforge.org/" target="_blank" rel="external">http://rubyforge.org/</a></p>
<ol>
<li>下载railsinstaller-2.2.3.exe<br> 这是Ruby环境的一键安装包，安装上它就可以安装上全部的Ruby环境。<br> 官网:<a href="http://railsinstaller.org/en" target="_blank" rel="external">http://railsinstaller.org/en</a><br> 此安装包包含如下内容：<br> Ruby 1.9.3<br>Rails 3.2<br>Bundler<br>Git<br>Sqlite<br>TinyTDS<br>SQL Server Support<br>DevKit</li>
</ol>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[CentOS下安装Redmine]]></title>
    <link href="/2014/09/09/2014-09-09-centos-install-redmine/"/>
    <id>/2014/09/09/2014-09-09-centos-install-redmine/</id>
    <published>2014-09-09T06:37:15.000Z</published>
    <updated>2014-11-15T05:36:37.000Z</updated>
    <content type="html"><![CDATA[<p>Redmine的安装主要分为两部分：</p>
<ol>
<li>Ruby+Rails的安装</li>
<li>Redmine的安装<br>先说一下系统环境，我安装的系统是CentOS 5，选择的Redmine版本是2.5.2，Ruby的版本是1.9.3，Rails的版本是3.2.19。<br>下面从以上两部分进行说明。</li>
</ol>
<h3 id="Ruby+Rails的安装">Ruby+Rails的安装</h3>
<p>Ruby的安装有3中方式：</p>
<ol>
<li>直接<code>yum install ruby</code></li>
<li>源码编译安装</li>
<li>采用RVM安装<br>以上3种方式我都尝试了，最后采用了RVM安装这种方式，这种方式也是最简单的。</li>
</ol>
<a id="more"></a>

<ol>
<li><p>下载RVM并且安装</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>curl -L <span class="keyword">https</span>://<span class="built_in">get</span>.rvm.io | bash -s stable
</pre></td></tr></table></figure>
</li>
<li><p>安装一些依赖库，编译安装其它软件或者库的时候会用到</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>yum install zlib zlib<span class="attribute">-devel</span> sqlite<span class="attribute">-devel</span>
yum install <span class="attribute">-y</span> gcc<span class="attribute">-c</span><span class="subst">++</span> patch readline readline<span class="attribute">-devel</span> zlib zlib<span class="attribute">-devel</span> libyaml<span class="attribute">-devel</span> libffi<span class="attribute">-devel</span> openssl<span class="attribute">-devel</span> make bzip2 autoconf automake libtool bison iconv<span class="attribute">-devel</span>
</pre></td></tr></table></figure>
</li>
<li><p>安装openssl，安装ruby的时候会使用到</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>rvm pkg <span class="keyword">install</span> openssl
</pre></td></tr></table></figure>
</li>
<li><p>指定openssl的位置来安装ruby</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>rvm install <span class="number">1.9</span><span class="number">.3</span> <span class="subst">--</span><span class="keyword">with</span><span class="attribute">-openssl</span><span class="attribute">-dir</span><span class="subst">=</span>/usr/<span class="built_in">local</span>/rvm/usr
</pre></td></tr></table></figure>
</li>
<li><p>指定使用Ruby版本</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>rvm <span class="keyword">use</span> <span class="number">1.9</span>.<span class="number">2</span>
</pre></td></tr></table></figure>
</li>
<li><p>安装Rails</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>gem <span class="keyword">install</span> rails
</pre></td></tr></table></figure>

</li>
</ol>
<p>经过以上步骤，Ruby和Rails就安装完毕了。<br>安装完Ruby之后，建议更改一下gem的镜像地址，原因你懂的。可以改到淘宝的gem镜像，参考一下网址：<a href="http://ruby.taobao.org" target="_blank" rel="external">http://ruby.taobao.org/</a>。上面有更改gem镜像的详细方法。</p>
<h3 id="Redmine的安装">Redmine的安装</h3>
<p>最推荐的做法是参考官方wiki（<a href="http://www.redmine.org/projects/redmine/wiki/RedmineInstall）" target="_blank" rel="external">http://www.redmine.org/projects/redmine/wiki/RedmineInstall）</a></p>
<ol>
<li><p>准备Redmine需要用到的数据库环境<br> 1.1. 修改Redmine数据库配置文件<br> 进入Redmine目录</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre><span class="keyword">cp</span> config/database<span class="preprocessor">.yml</span><span class="preprocessor">.example</span> config/database<span class="preprocessor">.yml</span>  
vi database<span class="preprocessor">.yml</span>
</pre></td></tr></table></figure><br>按照下面的内容进行修改<br><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre><span class="attribute">production</span>: <span class="string"> </span>
<span class="attribute">adapter</span>: <span class="string">mysql2  </span>
<span class="attribute">database</span>: <span class="string">db_redmine  </span>
<span class="attribute">host</span>: <span class="string">localhost  </span>
<span class="attribute">username</span>: <span class="string">root  </span>
<span class="attribute">password</span>: <span class="string">&lt;你的mysql密码&gt;  </span>
<span class="attribute">ps</span>: <span class="string">其中的一些值需要根据实际情况</span>
</pre></td></tr></table></figure>

<p> 1.2. 进入Mysql创建数据库</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="operator"><span class="keyword">create</span> <span class="keyword">database</span> redmine <span class="keyword">character</span> <span class="keyword">set</span> utf8;</span>
</pre></td></tr></table></figure>
</li>
<li><p>初始化Redmine数据库环境</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="attribute">rake db:migrate RAILS_ENV</span>=<span class="string">production</span>
</pre></td></tr></table></figure><br>执行此命令的时候会出现以下错误：<br><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>Could <span class="operator">not</span> find gem <span class="string">'mocha (~&gt; 1.0.0) ruby'</span> <span class="operator">in</span> <span class="operator">the</span> gems available <span class="command"><span class="keyword">on</span> <span class="title">this</span> <span class="title">machine</span>.</span>
Run `bundle install` <span class="built_in">to</span> install missing gems.
</pre></td></tr></table></figure><br>报这个错误的原因是因为缺少<code>mocha</code>这个gem，类似的还有很多gem都缺失。解决方法就是根据提示一个一个安装（类似于<code>gem install mocha -v=1.0.0</code>这样的命令），另一种解决办法是使用<code>bundle install</code>自动安装所缺少的gem，推荐使用这种方式，这种方式会自动帮你下载所依赖的gem，并且还能解决它们之间的版本冲突问题。<br>通过<code>bundle install</code>命令基本可以安装上所有依赖的gem，除了一个，<code>rmagick</code>，这个gem还需要依赖<code>ImageMagick</code>，他是用于处理一些图片转换之类的工作的。由于<code>rmagick</code>需要依赖<code>ImageMagick</code>，所以使用<code>bundle install</code>会安装失败，需要现在系统中安装<code>ImageMagick</code>。<br>解决方法如下：<br> 2.1. 如果你的CentOS版本比较新，可直接采用yum安装<br> <figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>	yum <span class="keyword">install</span> ImageMagick-devel
</pre></td></tr></table></figure>

<p> 2.2. 源码编译安装<br> 去官网下载源码(<a href="http://www.imagemagick.org/script/install-source.php#unix" target="_blank" rel="external">http://www.imagemagick.org/script/install-source.php#unix</a>)<br> 上面有安装教程，建议安装上面的步骤进行安装。<br> 下面列出我安装时执行的命令：</p>
 <figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>	tar xvzf ImageMagick<span class="preprocessor">.tar</span><span class="preprocessor">.gz</span>
    cd ImageMagick-<span class="number">6.8</span><span class="number">.9</span>
    ./configure
    make
    make install
</pre></td></tr></table></figure>

<p> 经过上面的步骤将gem都安装完之后，还需要再次执行<code>rake db:migrate RAILS_ENV=production</code>，这一步的主要作用是在数据库中生成Redmine需要的数据库表。</p>
</li>
<li><p>生成Redmine的Session存储</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>rake generate_secret_token
</pre></td></tr></table></figure>
</li>
<li><p>启动Redmine<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>ruby script/rails server webrick <span class="operator">-e</span> production
</pre></td></tr></table></figure><br>这条命令不是后台运行，建议使用如下命令，让redmie在后台运行<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>ruby script/rails server <span class="attribute">-e</span> production <span class="attribute">-d</span> <span class="subst">&gt;</span> /dev/<span class="built_in">null</span> <span class="number">2</span><span class="subst">&gt;&</span><span class="number">1</span> <span class="subst">&</span>
</pre></td></tr></table></figure><br>可将上述命令加入/etc/local中，使得Redmine可以在系统启动时就启动。</p>
</li>
</ol>
<p>在使用过程中可能会遇到如下错误：</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>ActionView::Template::Error (incompatible <span class="typename">character</span> encodings: UTF-<span class="number">8</span> <span class="keyword">and</span> ASCII-<span class="number">8</span><span class="typename">BIT</span>)
</pre></td></tr></table></figure><br>解决方法如下：<br><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre><span class="tag">rake</span> <span class="tag">assets</span><span class="pseudo">:precompile</span>
然后重启<span class="tag">rails</span> <span class="tag">server</span>。
</pre></td></tr></table></figure>

<h3 id="插件安装">插件安装</h3>
<p>Redmine还可以安装一些插件，来帮助我们进行项目管理。<br>我们现在安装的插件有crumpm、code review、scrum、Aginle。<br>code review下载地址:<a href="http://www.redmine.org/plugins/codereview" target="_blank" rel="external">http://www.redmine.org/plugins/codereview</a><br>scrum下载地址:<a href="https://redmine.ociotec.com/projects/redmine-plugin-scrum" target="_blank" rel="external">https://redmine.ociotec.com/projects/redmine-plugin-scrum</a><br>Aginle下载地址:<a href="http://www.redmine.org/plugins/redmine_agile" target="_blank" rel="external">http://www.redmine.org/plugins/redmine_agile</a></p>
<p>插件安装步骤:</p>
<ol>
<li>下载插件，解压到Redmine安装目录下的plugins文件夹下</li>
<li>在Redmine安装目录下执行:<figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="attribute">rake redmine:plugins:migrate RAILS_ENV</span>=<span class="string">production</span>
</pre></td></tr></table></figure></li>
<li>重启Redmine</li>
</ol>
<p>安装过程的参考资料如下：</p>
<ol>
<li><a href="http://lxiaodao.iteye.com/blog/1579992" target="_blank" rel="external">http://lxiaodao.iteye.com/blog/1579992</a></li>
<li><a href="http://note.youdao.com/share/?id=610d4aea90c5d7281b61dfcb1cd41906&amp;type=note" target="_blank" rel="external">http://note.youdao.com/share/?id=610d4aea90c5d7281b61dfcb1cd41906&amp;type=note</a></li>
<li><a href="http://blog.sina.com.cn/s/blog_8254427901016z1l.html" target="_blank" rel="external">http://blog.sina.com.cn/s/blog_8254427901016z1l.html</a></li>
</ol>
]]></content>
    <summary type="html"><![CDATA[<p>Redmine的安装主要分为两部分：</p>
<ol>
<li>Ruby+Rails的安装</li>
<li>Redmine的安装<br>先说一下系统环境，我安装的系统是CentOS 5，选择的Redmine版本是2.5.2，Ruby的版本是1.9.3，Rails的版本是3.2.19。<br>下面从以上两部分进行说明。</li>
</ol>
<h3 id="Ruby+Rails的安装">Ruby+Rails的安装</h3>
<p>Ruby的安装有3中方式：</p>
<ol>
<li>直接<code>yum install ruby</code></li>
<li>源码编译安装</li>
<li>采用RVM安装<br>以上3种方式我都尝试了，最后采用了RVM安装这种方式，这种方式也是最简单的。</li>
</ol>
]]></summary>
    
      <category term="linux" scheme="/tags/linux/"/>
    
      <category term="redmine" scheme="/tags/redmine/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[code-standards]]></title>
    <link href="/2014/07/19/code-standards/"/>
    <id>/2014/07/19/code-standards/</id>
    <published>2014-07-19T14:42:52.000Z</published>
    <updated>2014-11-14T15:35:47.000Z</updated>
    <content type="html"><![CDATA[<h1 id="后端">后端</h1>
<hr>
<h2 id="工程结构">工程结构</h2>
<p>分为<code>service</code>和<code>web</code></p>
<h2 id="注释">注释</h2>
<ol>
<li><p>类头要写明该类的职责是什么。<br>for example:<br><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="javadoc">/**
 * 职责
 *<span class="javadoctag"> @Description</span>
 *
 *<span class="javadoctag"> @author</span> zhangteng
 *<span class="javadoctag"> @email</span> zhangt@pandawork.net
 *<span class="javadoctag"> @time</span>: 2014/7/9 14:25
 */</span>
</pre></td></tr></table></figure></p>
<a id="more"></a>
</li>
<li><p>方法要写明该方法的功能是什么。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre><span class="javadoc">/**
 * 获取分页列表
 *
 *<span class="javadoctag"> @param</span> curPage
 *<span class="javadoctag"> @param</span> code
 *<span class="javadoctag"> @param</span> name
 *<span class="javadoctag"> @param</span> startTime
 *<span class="javadoctag"> @param</span> endTime
 *<span class="javadoctag"> @return</span>
 */</span>
</pre></td></tr></table></figure></li>
<li>方法里面要有适当的注释。不能写了一个方法100行，一个注释都没有。</li>
<li>数据库表要有一个总的声明，每个字段有相关说明。</li>
<li>实体或者业务修改，也要修改相关数据表中表对应的字段说明。保持一致。</li>
</ol>
<h2 id="后端规范">后端规范</h2>
<h3 id="类名称">类名称</h3>
<ol>
<li>以大写字母开头。</li>
<li>以驼峰方式命名。</li>
</ol>
<h3 id="属性名、方法名">属性名、方法名</h3>
<ol>
<li>以小写字母开头。</li>
<li>以驼峰方式命名。</li>
</ol>
<h3 id="常量命名规范">常量命名规范</h3>
<ol>
<li>所有字母大写</li>
<li>单词之间用’_’分隔</li>
</ol>
<h3 id="service,mapper方法名">service,mapper方法名</h3>
<p>方法名，根据不同的功能，按照不同的前缀进行设计。如下表：</p>
<table>
<thead>
<tr>
<th>功能说明</th>
<th>前缀</th>
</tr>
</thead>
<tbody>
<tr>
<td>计算数量</td>
<td>count</td>
</tr>
<tr>
<td>获取列表</td>
<td>list</td>
</tr>
<tr>
<td>查询功能</td>
<td>query</td>
</tr>
<tr>
<td>创建</td>
<td>add</td>
</tr>
<tr>
<td>删除</td>
<td>del</td>
</tr>
<tr>
<td>修改</td>
<td>update</td>
</tr>
</tbody>
</table>
<h3 id="controller命名规范">controller命名规范</h3>
<table>
<thead>
<tr>
<th>功能说明</th>
<th>前缀</th>
</tr>
</thead>
<tbody>
<tr>
<td>计算数量</td>
<td>count</td>
</tr>
<tr>
<td>获取列表</td>
<td>list</td>
</tr>
<tr>
<td>查询功能</td>
<td>query</td>
</tr>
<tr>
<td>创建</td>
<td>add</td>
</tr>
<tr>
<td>删除</td>
<td>del</td>
</tr>
<tr>
<td>修改</td>
<td>update</td>
</tr>
</tbody>
</table>
<p>如果是ajax，则需要在此前加上ajax。例如：<br>要通过ajax按照ID删除一个产品，方法名为ajaxDelProductById</p>
<h3 id="URL规范">URL规范</h3>
<h4 id="URL结构">URL结构</h4>
<p>下面，我们以用户为例。</p>
<ul>
<li>CREATE<br>/user/new        GET              这个Url负责跳转到提交表单的页面，用Get方法<br>/user            POST             负责接收表单提交的数据，用POST方法</li>
<li>DELETE<br>/user/{id}/del   GET              跳转到提交删除请求的页面，用GET方法（可选）<br>/user/{id}       DELETE           负责接收要删除的用户的数据，用DELETE方法</li>
<li>UPDATE<br>/user/{id}/update     GET         跳转到用户修改的页面，用GET方法<br>/user/{id}       PUT              负责接收表单提交的数据，修改用户，用PUT方法</li>
<li>READ<br>/user            GET              跳转到查看用户列表的页面，用GET方法<br>/user/{id}       GET              跳转到查看某个用户的页面，用GET方法</li>
<li>OTHER<br>/user/{id}/lock  PUT                有些时候，为了表示某一动作对用户产生的变化，我们这样命名，比如用户的锁定</li>
<li>分页<br>/user/{curPage} GET              大家可以用这个来进行获取分页列表</li>
</ul>
<h3 id="mapper层SQL语句书写规范">mapper层SQL语句书写规范</h3>
<p>书写SQL语句时，SQL中的关键字全部采用大写，如下所示</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="operator"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="string">`t_quality_check_item`</span></span>
</pre></td></tr></table></figure><br>SELECT、FROM、INSERT INTO、UPDATE、DELETE、AND、OR、LIKE、LIMIT、ORDER等关键字，在mapper中书写SQL语句时均采用大写。<br><br>### 后端开发注意事项<br>1. 职责单一化<br>要确保所写的程序职责单一，例如，有ProductService，和一个DiscountService，两者的区别在于一个是对产品的操作，另外一个是折扣的业务，在ProductService中，出现直接调去DiscountMapper的方法。<br>如上例，一个方法可以，多了，整个工程会出现轮乱局面，正确做法是走discountService进行相关的折扣计算。<br>2. 重复方法<br>此类问题最为严重，禁止在同一个Service中，或在mapper中出现多个名称不一样，但功能一样的方法。<br><br>## 数据库<br>### 数据库表名命名规则<br>1. 表名由前缀和实际名字组成，前缀和实际名字之间使用“<em>”连接。前缀使用“t”，实际名字都使用小写单词，多个单词之间使用“</em>”连接。例如：t<em>student_info<br>2. 如果要进行分表时，表的命名直接在表名的后面加上分表的标志。例如，t_user001,t_user002,t_user003<br>3. 表名的构成有t</em>模块名称<em>自己的表名。<br><br>### 字段命名规则<br>1. 每一个表都将有一个自动id作为主健,逻辑上的主健作为第一组候选主健来定义,如果是数据库自动生成的编码，统一命名为：id;如果是自定义的逻辑上的编码则用缩写 加“id”的方法命名。<br>2. 采用前缀命名。给每个表的列名都采用统一的前缀，后面的单词或则缩写都以大写字母开头<br><br>### 数据表的存储引擎和索引约定规则<br>1. 现在所有表的存储引擎都要选择InnoDB，如果需要设为其他存储引擎的时，要特别说明。<br>2. 在建立查询时候，务必要建立好数据库的索引，在确保查询语句使用正确高效可靠以后，养成马上建立对于索引的习惯。<br>3. 索引名称格式如下：<br>    * index\</em>索引类型_表名_按照索引顺序编写字段名，以_为分隔符。<br>    <em> index_t_books_isbn（普通索引）
    </em> index_unique_t_books_isbn(构建唯一索引)<br><br>索引的类型一般有三种类型，分别是普通索引（数据库中的index）, 唯一索引（数据库中的index unique),全文索引，这个基本上我们不会使用。<br><br><figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre>url:{
    index:{
        login:{
            check: <span class="string">'${website}index/login/check'</span>
        }
    }
}
</pre></td></tr></table></figure>]]></content>
    <summary type="html"><![CDATA[<h1 id="后端">后端</h1>
<hr>
<h2 id="工程结构">工程结构</h2>
<p>分为<code>service</code>和<code>web</code></p>
<h2 id="注释">注释</h2>
<ol>
<li><p>类头要写明该类的职责是什么。<br>for example:<br><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre><span class="javadoc">/**
 * 职责
 *<span class="javadoctag"> @Description</span>
 *
 *<span class="javadoctag"> @author</span> zhangteng
 *<span class="javadoctag"> @email</span> zhangt@pandawork.net
 *<span class="javadoctag"> @time</span>: 2014/7/9 14:25
 */</span>
</pre></td></tr></table></figure></p>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[grub2修复windows引导]]></title>
    <link href="/2014/07/12/grub2-repair-windows/"/>
    <id>/2014/07/12/grub2-repair-windows/</id>
    <published>2014-07-12T04:39:43.000Z</published>
    <updated>2014-11-14T15:35:55.000Z</updated>
    <content type="html"><![CDATA[<p>可参考网址<a href="http://blog.csdn.net/hengyunabc/article/details/6071683" target="_blank" rel="external">http://blog.csdn.net/hengyunabc/article/details/6071683</a></p>
<p>今天装了个centos 7，进去之后发现没有windows引导了，centos 7开始用grub 2引导了。<br>首先可以试试:</p>
<p><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>$ gurb2<span class="attribute">-mkconfig</span> <span class="attribute">-o</span> /boot/grub/grub<span class="built_in">.</span>cfg
</pre></td></tr></table></figure><br>它非常智能，能自动检测电脑上安装的操作系统，将它们加入到引导中去。<br>不过，有时候它也不好使，就像我今天这样。</p>
<a id="more"></a>

<p>可以采用第二种方式，手动修改/boot/grub/grub.cfg</p>
<p>首先查看分区的UUID</p>
<p><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="variable">$ </span>blkid
</pre></td></tr></table></figure><br>找到windows所在分区的UUID。一定要记住UUID，不要记住分区号，因为分区号有可能改变，但是UUID一定不会变。<br>然后修改grub.cfg</p>
<p><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre><span class="variable">$ </span>vim /boot/grub/grub.cfg
</pre></td></tr></table></figure><br>在该文件中加入如下内容:</p>
<p><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>menuentry <span class="string">"windows 8"</span> {
    insmod chain
    insmod ntfs
    search <span class="subst">--</span>fs<span class="attribute">-uuid</span> <span class="subst">--</span><span class="built_in">set</span> <span class="number">10</span>ac99d8ac99b8a4
    chainloader <span class="subst">+</span><span class="number">1</span>
}
</pre></td></tr></table></figure><br>其中的“10ac99d8ac99b8a4”要替换为上一步记住的UUID。</p>
<p>最后，重启电脑就可以看到windows 8的引导了，选择就可以进入系统了。</p>
]]></content>
    <summary type="html"><![CDATA[<p>可参考网址<a href="http://blog.csdn.net/hengyunabc/article/details/6071683" target="_blank" rel="external">http://blog.csdn.net/hengyunabc/article/details/6071683</a></p>
<p>今天装了个centos 7，进去之后发现没有windows引导了，centos 7开始用grub 2引导了。<br>首先可以试试:</p>
<p><figure class="highlight sh"><table><tr><td class="gutter"><pre>1
</pre></td><td class="code"><pre>$ gurb2<span class="attribute">-mkconfig</span> <span class="attribute">-o</span> /boot/grub/grub<span class="built_in">.</span>cfg
</pre></td></tr></table></figure><br>它非常智能，能自动检测电脑上安装的操作系统，将它们加入到引导中去。<br>不过，有时候它也不好使，就像我今天这样。</p>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[markdown语法简介]]></title>
    <link href="/2014/07/07/markdown-grammar/"/>
    <id>/2014/07/07/markdown-grammar/</id>
    <published>2014-07-07T12:41:20.000Z</published>
    <updated>2014-11-14T15:36:17.000Z</updated>
    <content type="html"><![CDATA[<p>本文摘抄自<a href="http://wowubuntu.com/markdown/" target="_blank" rel="external">http://wowubuntu.com/markdown/</a>，旨在联系一下markdown的语法，同时也向大家介绍一下markdown的语法，方便大家和自己查阅。</p>
<hr>
<h1 id="Markdown_语法说明（简体中文版）">Markdown 语法说明（简体中文版）</h1>
<ul>
<li><a href="#overview">概述</a><ul>
<li><a href="#philosophy">宗旨</a></li>
<li><a href="#html">兼容 HTML</a></li>
<li><a href="#autoescape">特殊字符自动转换</a></li>
</ul>
</li>
<li><a href="#block">区块元素</a><ul>
<li><a href="#p">段落和换行</a></li>
<li><a href="#header">标题</a></li>
<li><a href="#blockquote">区块引用</a></li>
<li><a href="#list">列表</a></li>
<li><a href="#precode">代码区块</a></li>
<li><a href="#hr">分割线</a></li>
</ul>
</li>
<li><a href="#span">区段元素</a><ul>
<li><a href="#link">链接</a></li>
<li><a href="#em">强调</a></li>
<li><a href="#code">代码</a></li>
<li><a href="#img">图片</a></li>
</ul>
</li>
<li><a href="#misc">其它</a><ul>
<li><a href="#backslash">反斜杠</a></li>
<li><a href="#autolink">自动连接</a></li>
</ul>
</li>
<li><a href="#editor">Markdown 免费编辑器</a></li>
</ul>
<a id="more"></a>

<hr>
<h2 id="overview">概述</h2>

<h3 id="philosophy">宗旨</h3>

<p>Markdown的目标是实现「易读易写」。</p>
<p>可读性，无论如何，都是最重要的。一份使用Markdown格式撰写的文件应该可以直接以纯文本发布，并且看起来不会像是由许多标签或是格式指令所构成。Markdown语法受到一些既有text-to-HTML格式的影响，包括<a href="http://docutils.sourceforge.net/mirror/setext.html" target="_blank" rel="external">Setext</a>、<a href="http://www.aaronsw.com/2002/atx/" target="_blank" rel="external">atx</a>、<a href="http://textism.com/tools/textile/" target="_blank" rel="external">Textile</a>、<a href="http://docutils.sourceforge.net/rst.html" target="_blank" rel="external">reStructuredText</a>、<a href="http://www.triptico.com/software/grutatxt.html" target="_blank" rel="external">Grutatext</a>和<a href="http://ettext.taint.org/doc/" target="_blank" rel="external">EtText</a>，而最大灵感来源其实是纯文本电子邮件的格式。</p>
<p>总之，Markdown的语法全由一些符号所组成，这些符号经过精挑细选，其作用一目了然。比如：在文字两旁加上星号，看起来就像*强调*。Markdown的列表看起来，嗯，就是列表。Markdown的区块引用看起来就真的像是引用一段文字，就像你曾在电子邮件中见过的那样。</p>
<h3 id="html">兼容 HTML</h3>

<p>Markdown语法的目标是：成为一种适用于网络的<em>书写</em>语言。</p>
<p>Markdown不是想要取代HTML，甚至也没有要和它相近，他的语法种类很少，只对应HTML标记的一小部分。Markdown的构想<em>不是</em>要使得HTML文档更容易书写。在我看来，HTML已经很容易书写了。Markdown的理念是，能让文档更容易读、写和随意改。HTML是一种<em>发布</em>的格式，Markdown是一种<em>书写</em>的格式。就这样，Markdown的格式语法只涵盖纯文本可以涵盖的范围。</p>
<p>不在Markdown涵盖范围之内的标签，都可以直接在文档里面用HTMl撰写。不需要额外标注这是HTML或是Markdown；只要直接加标签就可以了。</p>
<p>要制约的只有一些HTML区块元素—比如<code>&lt;div&gt;</code>、<code>&lt;table&gt;</code>、<code>&lt;pre&gt;</code>、<code>&lt;p&gt;</code>等标签，必须在前后加上空行与其它内容区隔开，还要求它们的开始标签与结尾标签不能用制表符或空格来缩进。Markdown的生成器有足够只能，不会在HTML区块标签外加上不必要的<code>&lt;p&gt;</code>标签。</p>
<p>例子如下，在 Markdown 文件里加上一段 HTML 表格：</p>
<pre><code>这是一个普通段落。

<span class="tag">&lt;<span class="title">table</span>&gt;</span>
    <span class="tag">&lt;<span class="title">tr</span>&gt;</span>
        <span class="tag">&lt;<span class="title">td</span>&gt;</span>Foo<span class="tag">&lt;/<span class="title">td</span>&gt;</span>
    <span class="tag">&lt;/<span class="title">tr</span>&gt;</span>
<span class="tag">&lt;/<span class="title">table</span>&gt;</span>

这是另一个普通段落。
</code></pre><p>请注意，在 HTML 区块标签间的 Markdown 格式语法将不会被处理。比如，你在 HTML 区块内使用 Markdown 样式的<code>*强调*</code>会没有效果。</p>
<p>HTML的区段（行内）标签如<code>&lt;span&gt;</code>、<code>&lt;cite&gt;</code>、<code>&lt;del&gt;</code>可以在Markdown的段落、列表或是标题里随意使用。依照个人习惯，甚至可以不用Markdown格式，而直接此阿勇HTML标签来格式化。举例说明：如果比较喜欢HTML的<code>&lt;a&gt;</code>或<code>&lt;img&gt;</code>标签，可以直接使用这些标签，而不用Markdown提供的链接或是图像标签语法。</p>
<p>和处在HTML区块标签件不同，Markdown语法在HTML区段标签间是有效的。</p>
]]></content>
    <summary type="html"><![CDATA[<p>本文摘抄自<a href="http://wowubuntu.com/markdown/" target="_blank" rel="external">http://wowubuntu.com/markdown/</a>，旨在联系一下markdown的语法，同时也向大家介绍一下markdown的语法，方便大家和自己查阅。</p>
<hr>
<h1 id="Markdown_语法说明（简体中文版）">Markdown 语法说明（简体中文版）</h1>
<ul>
<li><a href="#overview">概述</a><ul>
<li><a href="#philosophy">宗旨</a></li>
<li><a href="#html">兼容 HTML</a></li>
<li><a href="#autoescape">特殊字符自动转换</a></li>
</ul>
</li>
<li><a href="#block">区块元素</a><ul>
<li><a href="#p">段落和换行</a></li>
<li><a href="#header">标题</a></li>
<li><a href="#blockquote">区块引用</a></li>
<li><a href="#list">列表</a></li>
<li><a href="#precode">代码区块</a></li>
<li><a href="#hr">分割线</a></li>
</ul>
</li>
<li><a href="#span">区段元素</a><ul>
<li><a href="#link">链接</a></li>
<li><a href="#em">强调</a></li>
<li><a href="#code">代码</a></li>
<li><a href="#img">图片</a></li>
</ul>
</li>
<li><a href="#misc">其它</a><ul>
<li><a href="#backslash">反斜杠</a></li>
<li><a href="#autolink">自动连接</a></li>
</ul>
</li>
<li><a href="#editor">Markdown 免费编辑器</a></li>
</ul>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[新博客的第一篇博文]]></title>
    <link href="/2014/07/06/new-blog-first-post/"/>
    <id>/2014/07/06/new-blog-first-post/</id>
    <published>2014-07-06T12:59:23.000Z</published>
    <updated>2014-07-06T13:08:55.000Z</updated>
    <content type="html"><![CDATA[<p>以前在github上用octopress挂了一个博客，但是用它还得装ruby，感觉比较麻烦（主要还是不懂ruby）。<br>前段时间，看到有人用hexo搭建博客，我也试了试。hexo是基于node，比octopress方便多了，就转了过来。<br>这是他的官网<a href="http://hexo.io/" target="_blank" rel="external">http://hexo.io/</a>，关于具体怎么搭建，我就不多说了，官网写得和详细，直接上官方文档的链接<a href="http://hexo.io/docs/index.html" target="_blank" rel="external">http://hexo.io/docs/index.html</a>。<br>说说我遇到的问题吧，按照官网说的做了，我用<code>hexo deploy</code>，一直deploy上去，也不知道为啥，可能主要还是我对node和git都不熟悉吧。<br>最后我是手动deploy的。具体命令如下：</p>
<p><figure class="highlight bash"><table><tr><td class="gutter"><pre>1
2
3
4
</pre></td><td class="code"><pre>$ hexo clean
$ hexo deploy --generate
$ <span class="built_in">cd</span> .deploy
$ git push -u origin master
</pre></td></tr></table></figure><br>命令都是在hexo博客的目录下执行的。<br>另外奉上我使用的主题地址:<a href="http://yangjian.me/pacman/hello/introducing-pacman-theme/" target="_blank" rel="external">http://yangjian.me/pacman/hello/introducing-pacman-theme/</a></p>
]]></content>
    
    
  </entry>
  
  <entry>
    <title><![CDATA[jquery使用笔记]]></title>
    <link href="/2013/11/01/2013-11-01-jquery-study/"/>
    <id>/2013/11/01/2013-11-01-jquery-study/</id>
    <published>2013-11-01T02:43:00.000Z</published>
    <updated>2014-11-15T05:39:07.000Z</updated>
    <content type="html"><![CDATA[<ol>
<li>ajax请求，注意最后一个值的地方没有逗号<figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre>$.ajax({  
    type: <span class="string">"POST"</span>,
    url: <span class="string">"mystructs/hello_jsonTest.action"</span>,
    data: {
        number: $(<span class="string">"#number"</span>).val(),
        userId: $(<span class="string">'#userId'</span>).val() 
    },
    dataType: <span class="string">"text"</span>,  <span class="comment">//ajax返回值设置为text（json格式也可用它返回，可打印出结果，也可设置成json）</span>
    success: <span class="function"><span class="keyword">function</span><span class="params">(json)</span> {</span>
        <span class="keyword">var</span> res = $.parseJSON(json);
        alert(res.result);
    },
    error: <span class="function"><span class="keyword">function</span><span class="params">(json)</span> {</span>
        alert(json);
    }
});
</pre></td></tr></table></figure>

</li>
</ol>
<a id="more"></a>

<ol>
<li>jquery改变值<figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
</pre></td><td class="code"><pre>$(<span class="string">'#id'</span>).val(<span class="string">'value'</span>);
$(<span class="string">'#id'</span>).html(<span class="string">'value'</span>);
</pre></td></tr></table></figure></li>
<li>jquery获取radio中被选中的那个元素<figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="keyword">var</span> val = $(<span class="string">'input:radio[name="ra"]:checked'</span>).val();
<span class="keyword">if</span>(val != <span class="literal">null</span>) {
    alert(val);
} <span class="keyword">else</span> {        
    ...
}
</pre></td></tr></table></figure><br>判读radio是否被选中<br><figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre>$(<span class="string">'input:radio[name="ra"]'</span>).each(<span class="function"><span class="keyword">function</span><span class="params">()</span> {</span>
    <span class="comment">//alert($(this).val());</span>
    <span class="keyword">if</span>($(<span class="keyword">this</span>).attr(<span class="string">"checked"</span>) == <span class="string">"checked"</span>) {
        alert($(<span class="keyword">this</span>).val());
    }
});
</pre></td></tr></table></figure></li>
<li>获取选中的checkbox<figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
</pre></td><td class="code"><pre>$(<span class="string">'input[name="chk"]:checked'</span>).each(<span class="function"><span class="keyword">function</span><span class="params">()</span>{</span>
    alert($(<span class="keyword">this</span>).val());
});
</pre></td></tr></table></figure><br>判读checkbox是否被选中<br><figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>$(<span class="string">'input:checkbox[name="chk"]'</span>).each(<span class="function"><span class="keyword">function</span><span class="params">()</span> {</span>
    <span class="keyword">if</span>($(<span class="keyword">this</span>).attr(<span class="string">"checked"</span>) == <span class="string">"checked"</span>) {
        alert($(<span class="keyword">this</span>).val());
    }
});
</pre></td></tr></table></figure>
</li>
</ol>
]]></content>
    <summary type="html"><![CDATA[<ol>
<li>ajax请求，注意最后一个值的地方没有逗号<figure class="highlight js"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre>$.ajax({  
    type: <span class="string">"POST"</span>,
    url: <span class="string">"mystructs/hello_jsonTest.action"</span>,
    data: {
        number: $(<span class="string">"#number"</span>).val(),
        userId: $(<span class="string">'#userId'</span>).val() 
    },
    dataType: <span class="string">"text"</span>,  <span class="comment">//ajax返回值设置为text（json格式也可用它返回，可打印出结果，也可设置成json）</span>
    success: <span class="function"><span class="keyword">function</span><span class="params">(json)</span> {</span>
        <span class="keyword">var</span> res = $.parseJSON(json);
        alert(res.result);
    },
    error: <span class="function"><span class="keyword">function</span><span class="params">(json)</span> {</span>
        alert(json);
    }
});
</pre></td></tr></table></figure>

</li>
</ol>
]]></summary>
    
      <category term="jquery" scheme="/categories/jquery/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[structs2返回json]]></title>
    <link href="/2013/10/30/2013-10-30-struts2-json/"/>
    <id>/2013/10/30/2013-10-30-struts2-json/</id>
    <published>2013-10-30T01:28:00.000Z</published>
    <updated>2014-11-15T05:38:58.000Z</updated>
    <content type="html"><![CDATA[<p>structs2返回本身支持返回json，只需要配置即可，我们也可以自己把json串写入servlet输出流中。</p>
<a id="more"></a>

<p>1.structs2本身对json的支持<br>在action中对需要返回的值进行设置，实体、java自带类型都可以。<br>如：</p>
<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre><span class="keyword">private</span> User user;
<span class="keyword">private</span> result result;

<span class="comment">/*   setter and getter   */</span>
<span class="keyword">public</span> String <span class="title">json</span>() {
    user.setUserName(<span class="string">"iris"</span>);
    result = <span class="string">"success"</span>;
    <span class="keyword">return</span> SUCCESS;
}
</pre></td></tr></table></figure><br>在配置文件中配置result的type为json</p>
<p><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre>&lt;<span class="constant">result</span>-types&gt;
    &lt;<span class="constant">result</span>-type <span class="property">name</span>=<span class="string">"json"</span> <span class="type">class</span>=<span class="string">"org.apache.struts2.json.JSONResult"</span>/&gt;
&lt;/<span class="constant">result</span>-types&gt;

&lt;action <span class="property">name</span>=<span class="string">"hello_*"</span> <span class="type">class</span>=<span class="string">"action.FirstAction"</span> method=<span class="string">"{1}"</span>&gt;
    &lt;<span class="constant">result</span> <span class="property">name</span>=<span class="string">"success"</span> type=<span class="string">"json"</span>&gt;&lt;/<span class="constant">result</span>&gt;
&lt;/action&gt;
</pre></td></tr></table></figure><br>注意result-types那段一定要加上，不加那个的就必须让action所在的package继承<code>json-default</code><br>2.把json数据写入servlet输出流中<br>在action中讲json数据直接写入servlet输出流中，action中的方法返回void<br>如：</p>
<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">newjsontest</span>() {
    HttpServletResponse response = ServletActionContext.getResponse();
    PrintWriter out = <span class="keyword">null</span>;
    <span class="keyword">try</span> {
        out = response.getWriter();
    User user = <span class="keyword">new</span> User();
    user.setUsername(<span class="string">"iris"</span>);
    user.setPassword(<span class="string">"iris"</span>);
    JSONObject jsonObject = JSONObject.fromObject(user);
    out.print(jsonObject.toString());
    out.flush();
    } <span class="keyword">catch</span> (IOException e) {
    e.printStackTrace();
    } <span class="keyword">finally</span> {
    <span class="keyword">if</span>(out != <span class="keyword">null</span>) {
        <span class="keyword">try</span> {
    	        out.close();
    	    } <span class="keyword">catch</span> (Exception e) {
            e.printStackTrace();
        }
        }
    }
}
</pre></td></tr></table></figure><br>这里用到了<code>net.sf.json.JSONObject</code>这个包，将实体直接转换成json，也可以不用这个包，直接手动拼json串，然后<code>out.write(jsonStr)</code>。</p>
]]></content>
    <summary type="html"><![CDATA[<p>structs2返回本身支持返回json，只需要配置即可，我们也可以自己把json串写入servlet输出流中。</p>
]]></summary>
    
  </entry>
  
  <entry>
    <title><![CDATA[sublime利用snippet生成代码模版]]></title>
    <link href="/2013/10/23/2013-10-23-sublime-snippet/"/>
    <id>/2013/10/23/2013-10-23-sublime-snippet/</id>
    <published>2013-10-23T06:20:00.000Z</published>
    <updated>2014-11-15T05:38:50.000Z</updated>
    <content type="html"><![CDATA[<p><code>tools-&gt;New Snippet</code>新建一个snippet，保存为**.sublime-snippet。<br>内容如下：  </p>
<a id="more"></a>

<p><figure class="highlight html"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="tag">&lt;<span class="title">snippet</span>&gt;</span>
    <span class="tag">&lt;<span class="title">content</span>&gt;</span>
    <span class="cdata">&lt;![CDATA[
&lt;!DOCTYPE HTML&gt; 
&lt;html&gt; 
&lt;head&gt; 
    &lt;meta charset="utf-8"&gt; 
    &lt;title&gt;${1}&lt;/title&gt; 
&lt;/head&gt;
&lt;body&gt;
    ${1}
&lt;/body&gt;
&lt;/html&gt;
    ]]&gt;</span>
    <span class="tag">&lt;/<span class="title">content</span>&gt;</span>
    <span class="comment">&lt;!-- Optional: Set a tabTrigger to define how to trigger the snippet --&gt;</span>
    <span class="tag">&lt;<span class="title">tabTrigger</span>&gt;</span>myhtml<span class="tag">&lt;/<span class="title">tabTrigger</span>&gt;</span>
    <span class="comment">&lt;!-- Optional: Set a scope to limit where the snippet will trigger --&gt;</span>
    <span class="comment">&lt;!-- &lt;scope&gt;source.python&lt;/scope&gt; --&gt;</span>
<span class="tag">&lt;/<span class="title">snippet</span>&gt;</span>sublime-snippet
</pre></td></tr></table></figure><br>重启sublime，新建文件输入myhtml，然后按<code>tab</code>。</p>
]]></content>
    <summary type="html"><![CDATA[<p><code>tools-&gt;New Snippet</code>新建一个snippet，保存为**.sublime-snippet。<br>内容如下：  </p>
]]></summary>
    
      <category term="sublime" scheme="/categories/sublime/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[struts2文件上传]]></title>
    <link href="/2013/10/23/2013-10-23-struts-uploadfile/"/>
    <id>/2013/10/23/2013-10-23-struts-uploadfile/</id>
    <published>2013-10-23T01:02:00.000Z</published>
    <updated>2014-11-15T05:38:38.000Z</updated>
    <content type="html"><![CDATA[<p>注意保持action中File的变量和jsp中input的name名相同。<br>action中定义变量：</p>
<a id="more"></a>

<p><figure class="highlight java"><table><tr><td class="gutter"><pre>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
27
28
29
30
31
32
</pre></td><td class="code"><pre><span class="keyword">package</span> action;
<span class="keyword">import</span> java.io.File;
<span class="keyword">import</span> java.io.FileInputStream;
<span class="keyword">import</span> java.io.FileOutputStream;
<span class="keyword">import</span> com.opensymphony.xwork2.ActionSupport;
<span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UploadFileAction</span> <span class="keyword">extends</span> <span class="title">ActionSupport</span> {</span>
    
    <span class="comment">// 上传的文件</span>
    <span class="keyword">private</span> File upload;
    
    <span class="comment">// 上传的文件名</span>
    <span class="keyword">private</span> String uploadFileName;
    
    <span class="comment">// 上传的文件类型</span>
    <span class="keyword">private</span> String uploadContentType;
    
    <span class="keyword">public</span> String <span class="title">execute</span>() <span class="keyword">throws</span> Exception {
        FileInputStream fis = <span class="keyword">new</span> FileInputStream(upload);
        File file = <span class="keyword">new</span> File(<span class="string">"E:/dsideal/upload/"</span> +  uploadFileName);
        FileOutputStream fos = <span class="keyword">new</span> FileOutputStream(file);
        <span class="keyword">byte</span>[] buffer = <span class="keyword">new</span> <span class="keyword">byte</span>[<span class="number">8912</span>];
        <span class="keyword">int</span> count = <span class="number">0</span>;
        <span class="keyword">while</span>((count = fis.read(buffer)) != -<span class="number">1</span>) {
            fos.write(buffer, <span class="number">0</span>, count);
        }
        fos.close();
        fis.close();
        <span class="keyword">return</span> SUCCESS;
    }
    
    <span class="comment">/* set、get method */</span>
}
</pre></td></tr></table></figure><br>jsp页面:</p>
<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>&lt;s:form action="mystruts/uploadFile.action" enctype="multipart/form-data"&gt;
    &lt;s:file name="upload" label="输入要上传的文件名字" /&gt;
    &lt;s:submit value="上传" /&gt;
    &lt;/s:form&gt;
&lt;/body&gt;
</pre></td></tr></table></figure><br>使用了struts标签，也可以直接使用html表单标签form、input</p>
]]></content>
    <summary type="html"><![CDATA[<p>注意保持action中File的变量和jsp中input的name名相同。<br>action中定义变量：</p>
]]></summary>
    
      <category term="struts" scheme="/categories/struts/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[JSON和bean互转]]></title>
    <link href="/2013/10/21/2013-10-21-json-to-bean/"/>
    <id>/2013/10/21/2013-10-21-json-to-bean/</id>
    <published>2013-10-21T01:32:00.000Z</published>
    <updated>2014-11-15T05:38:32.000Z</updated>
    <content type="html"><![CDATA[<p>需要用到的类：</p>
<pre><code>net<span class="preprocessor">.sf</span><span class="preprocessor">.json</span><span class="preprocessor">.JSONObject</span>  
</code></pre><p>在包<code>json-lib-2.3-jdk15</code>中</p>
<a id="more"></a>

<p>maven依赖：</p>
<p><figure class="highlight"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="tag">&lt;<span class="title">dependency</span>&gt;</span>
    <span class="tag">&lt;<span class="title">groupId</span>&gt;</span>net.sf.json-lib<span class="tag">&lt;/<span class="title">groupId</span>&gt;</span>
    <span class="tag">&lt;<span class="title">artifactId</span>&gt;</span>json-lib<span class="tag">&lt;/<span class="title">artifactId</span>&gt;</span>
    <span class="tag">&lt;<span class="title">version</span>&gt;</span>2.4<span class="tag">&lt;/<span class="title">version</span>&gt;</span>
    <span class="tag">&lt;<span class="title">classifier</span>&gt;</span>jdk15<span class="tag">&lt;/<span class="title">classifier</span>&gt;</span>
<span class="tag">&lt;/<span class="title">dependency</span>&gt;</span>
</pre></td></tr></table></figure><br>将bean转换成JSONObject，调用<code>JSONObject.fromObject(object)</code><br>如：</p>
<pre><code><span class="attribute">JSONObject jsonObject </span>=<span class="string"> JSONObject.fromObject(user);</span>
</code></pre><p>将JSONObject转换成bean，调用<code>JSONObject.toBean(jsonObject, beanClass)</code><br>如：</p>
<pre><code>User user = (User) JSONObject<span class="preprocessor">.toBean</span>(jsonObject, User<span class="preprocessor">.class</span>)<span class="comment">;</span>
</code></pre>]]></content>
    <summary type="html"><![CDATA[<p>需要用到的类：</p>
<pre><code>net<span class="preprocessor">.sf</span><span class="preprocessor">.json</span><span class="preprocessor">.JSONObject</span>  
</code></pre><p>在包<code>json-lib-2.3-jdk15</code>中</p>
]]></summary>
    
      <category term="java" scheme="/categories/java/"/>
    
  </entry>
  
  <entry>
    <title><![CDATA[删除Java集合中元素]]></title>
    <link href="/2013/10/13/2013-10-13-remove-elemetns/"/>
    <id>/2013/10/13/2013-10-13-remove-elemetns/</id>
    <published>2013-10-13T13:42:00.000Z</published>
    <updated>2014-11-15T05:38:24.000Z</updated>
    <content type="html"><![CDATA[<p>有时候我们需要删除list中的某个元素，最开始我会这样写：</p>
<a id="more"></a>

<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListTest</span> {</span>
    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span>(String[] args) {
        List&lt;Integer&gt; numbers = <span class="keyword">new</span> ArrayList();
        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>;i &lt;= <span class="number">10</span>; ++i) {
            numbers.add(i);
        }

        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; <span class="number">10</span>; ++i) {
            <span class="keyword">if</span>(numbers.get(i) == <span class="number">5</span>) {
                numbers.remove(i);
            }
        }

        System.out.println(numbers);
    }
}
</pre></td></tr></table></figure><br>这样写之后，会报错。因为list在循环中的时候是不可以删除它的元素的。<br>对上面的代码进行一点下改进就可以删除list中的元素了，就是在<code>remove</code>之后加个<code>break</code>就可以了。</p>
<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListTest</span> {</span>
    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span>(String[] args) {
        List&lt;Integer&gt; numbers = <span class="keyword">new</span> ArrayList();
        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>;i &lt;= <span class="number">10</span>; ++i) {
            numbers.add(i);
        }

        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; <span class="number">10</span>; ++i) {
            <span class="keyword">if</span>(numbers.get(i) == <span class="number">5</span>) {
                numbers.remove(i);
                <span class="keyword">break</span>;
            }
        }

        System.out.println(numbers);
    }
}
</pre></td></tr></table></figure><br>上面的方法适用于只删除一个元素，可有的时候我们需要删除多个元素，上面的方法虽可行，但需要为每个需要删除的元素写个for循环，这样效率太低了。<br>使用<code>Iterator</code>可以完成上面的操作。</p>
<p><figure class="highlight java"><table><tr><td class="gutter"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ListTest</span> {</span>
    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span>(String[] args) {
        List&lt;Integer&gt; numbers = <span class="keyword">new</span> ArrayList();
        <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>;i &lt;= <span class="number">10</span>; ++i) {
            numbers.add(i);
        }

        <span class="keyword">for</span>(Iterator it=numbers.iterator() ;it.hasNext(); ) {
            Integer tmp = (Integer) it.next();
            <span class="keyword">if</span>(tmp == <span class="number">5</span>) {
                it.remove();
            }
            <span class="keyword">if</span>(tmp == <span class="number">7</span>) {
                it.remove();
            }
        }

        System.out.println(numbers);
    }
}
</pre></td></tr></table></figure><br>上面的方法虽都可以删除元素，但都需要for循环，效率不高，但没有找到更好的方法。感觉java的Iterator没有c++的那么只能，用起来没有c++顺手。</p>
<blockquote>
<p>对Java的基础知识了解越多，代码就会写得越简洁</p>
</blockquote>
]]></content>
    <summary type="html"><![CDATA[<p>有时候我们需要删除list中的某个元素，最开始我会这样写：</p>
]]></summary>
    
      <category term="java" scheme="/categories/java/"/>
    
  </entry>
  
</feed>
