1 Star 0 Fork 0

mirroro/caifenglin

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
atom.xml 364.89 KB
一键复制 编辑 原始数据 按行查看 历史
mirroro 提交于 2019-03-13 22:44 . Site updated: 2019-03-13 22:44:43
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>飘絮不飘</title>
<subtitle>CaiFengLin</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://smartdot.club/"/>
<updated>2019-03-13T10:42:29.060Z</updated>
<id>http://smartdot.club/</id>
<author>
<name>caifenglin</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>第2章 SpringCloud服务注册与发现</title>
<link href="http://smartdot.club/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6/Spring%20Cloud/%E7%AC%AC2%E7%AB%A0%20SpringCloud%E6%9C%8D%E5%8A%A1%E6%B3%A8%E5%86%8C%E4%B8%8E%E5%8F%91%E7%8E%B0/"/>
<id>http://smartdot.club/微服务框架/Spring Cloud/第2章 SpringCloud服务注册与发现/</id>
<published>2019-03-11T12:17:09.000Z</published>
<updated>2019-03-13T10:42:29.060Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="什么是服务治理"><a href="#什么是服务治理" class="headerlink" title="什么是服务治理"></a>什么是服务治理</h2><p>在传统rpc远程调用中,服务与服务依赖关系,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。</p><h2 id="服务注册与发现"><a href="#服务注册与发现" class="headerlink" title="服务注册与发现"></a>服务注册与发现</h2><p>在服务注册与发现中,有一个注册中心,当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。<br>另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,让后在实现rpc调用。</p><h2 id="搭建注册中心"><a href="#搭建注册中心" class="headerlink" title="搭建注册中心"></a>搭建注册中心</h2><h3 id="常用注册中心框架"><a href="#常用注册中心框架" class="headerlink" title="常用注册中心框架"></a>常用注册中心框架</h3><p>1) 服务注册与发现原理 在任何rpc远程框架中,都会有一个注册中心<br>2) 注册中心概念: 存放服务地址相关信息(接口地址)</p><p>SpringCloud中支持以下三种注册中心<br>Eurcka、Consul(go语言编写)、Zookeeper<br>Dubbo支持常用两种Redis和Zookeeper</p><p>服务提供者: 提供服务接口意思<br>服务消费者: 调用别人接口进行使用<br>一个服务既可以作为提供者,也可以作为消费者。</p><p>注:eureka 英[juˈri:kə] 美[jʊ’ri:kə]</p><h3 id="注册中心环境搭建"><a href="#注册中心环境搭建" class="headerlink" title="注册中心环境搭建"></a>注册中心环境搭建</h3><h4 id="Maven依赖信息"><a href="#Maven依赖信息" class="headerlink" title="Maven依赖信息"></a>Maven依赖信息</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 管理依赖 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>Finchley.M7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">type</span>&gt;</span>pom<span class="tag">&lt;/<span class="name">type</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">scope</span>&gt;</span>import<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--SpringCloud eureka-server --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-server<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 注意: 这里必须要添加, 否者各种依赖有问题 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">id</span>&gt;</span>spring-milestones<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>Spring Milestones<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repo.spring.io/libs-milestone<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">enabled</span>&gt;</span>false<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="application-yml"><a href="#application-yml" class="headerlink" title="application.yml"></a>application.yml</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###服务端口号</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8100</span></span><br><span class="line"><span class="comment">###eureka 基本信息配置</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> instance:</span></span><br><span class="line"> <span class="comment">###注册到eurekaip地址</span></span><br><span class="line"><span class="attr"> hostname:</span> <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> serviceUrl:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://$&#123;eureka.instance.hostname&#125;:$&#123;server.port&#125;/eureka/</span></span><br><span class="line"> <span class="comment">###因为自己是为注册中心,不需要自己注册自己</span></span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">false</span></span><br><span class="line"> <span class="comment">###因为自己是为注册中心,不需要检索服务</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><h4 id="启动Eureka服务"><a href="#启动Eureka服务" class="headerlink" title="启动Eureka服务"></a>启动Eureka服务</h4><p>@EnableEurekaServer作用:开启eurekaServer<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@EnableEurekaServer</span></span><br><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppEureka</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">SpringApplication.run(AppEureka.class, args);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p><img src="/images/springcloud/第2章/01.png" alt="SpringCloud"></p><h3 id="注册服务提供者"><a href="#注册服务提供者" class="headerlink" title="注册服务提供者"></a>注册服务提供者</h3><p>项目案例:实现会员服务(提供者)springcloud-2.0-member调用订单服务(消费者)springcloud-2.0-order</p><h4 id="Maven依赖信息-1"><a href="#Maven依赖信息-1" class="headerlink" title="Maven依赖信息"></a>Maven依赖信息</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 管理依赖 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>Finchley.M7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">type</span>&gt;</span>pom<span class="tag">&lt;/<span class="name">type</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">scope</span>&gt;</span>import<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- SpringBoot整合Web组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- SpringBoot整合eureka客户端 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 注意: 这里必须要添加, 否者各种依赖有问题 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">id</span>&gt;</span>spring-milestones<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>Spring Milestones<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repo.spring.io/libs-milestone<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">enabled</span>&gt;</span>false<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="application-yml-1"><a href="#application-yml-1" class="headerlink" title="application.yml"></a>application.yml</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###服务启动端口号</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8000</span></span><br><span class="line"><span class="comment">###服务名称(服务注册到eureka名称) </span></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line"><span class="attr"> application:</span></span><br><span class="line"><span class="attr"> name:</span> <span class="string">app-itmayiedu-member</span></span><br><span class="line"><span class="comment">###服务注册到eureka地址</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> service-url:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://localhost:8100/eureka</span></span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"><span class="comment">###因为该应用为注册中心,不会注册自己</span></span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="comment">###是否需要从eureka上获取注册信息</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="服务接口"><a href="#服务接口" class="headerlink" title="服务接口"></a>服务接口</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MemberController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/getMember"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getMember</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"this is getMember"</span>;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="启动会员服务"><a href="#启动会员服务" class="headerlink" title="启动会员服务"></a>启动会员服务</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="meta">@EnableEurekaClient</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppMember</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">SpringApplication.run(AppMember.class, args);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="/images/springcloud/第2章/02.png" alt="SpringCloud"></p><h3 id="服务消费者"><a href="#服务消费者" class="headerlink" title="服务消费者"></a>服务消费者</h3><h4 id="Maven依赖信息-2"><a href="#Maven依赖信息-2" class="headerlink" title="Maven依赖信息"></a>Maven依赖信息</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 管理依赖 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>Finchley.M7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">type</span>&gt;</span>pom<span class="tag">&lt;/<span class="name">type</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">scope</span>&gt;</span>import<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- SpringBoot整合Web组件 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- SpringBoot整合eureka客户端 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 注意: 这里必须要添加, 否者各种依赖有问题 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">id</span>&gt;</span>spring-milestones<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>Spring Milestones<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repo.spring.io/libs-milestone<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">enabled</span>&gt;</span>false<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="Application-yml配置"><a href="#Application-yml配置" class="headerlink" title="Application.yml配置"></a>Application.yml配置</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###服务启动端口号</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8001</span></span><br><span class="line"><span class="comment">###服务名称(服务注册到eureka名称) </span></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line"><span class="attr"> application:</span></span><br><span class="line"><span class="attr"> name:</span> <span class="string">app-itmayiedu-order</span></span><br><span class="line"><span class="comment">###服务注册到eureka地址</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> service-url:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://localhost:8100/eureka</span></span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"><span class="comment">###因为该应用为注册中心,不会注册自己</span></span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="comment">###是否需要从eureka上获取注册信息</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="使用rest方式调用服务"><a href="#使用rest方式调用服务" class="headerlink" title="使用rest方式调用服务"></a>使用rest方式调用服务</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OrderController</span> </span>&#123;</span><br><span class="line"><span class="meta">@Autowired</span></span><br><span class="line"><span class="keyword">private</span> RestTemplate restTemplate;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/getorder"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">getOrder</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="comment">// order 使用rpc 远程调用技术 调用 会员服务</span></span><br><span class="line">String memberUrl = <span class="string">"http://app-itmayiedu-member/getMember"</span>;</span><br><span class="line">String result = restTemplate.getForObject(memberUrl, String.class);</span><br><span class="line">System.out.println(<span class="string">"订单服务调用会员服务,result:"</span> + result);</span><br><span class="line"><span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="启动消费者服务"><a href="#启动消费者服务" class="headerlink" title="启动消费者服务"></a>启动消费者服务</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="meta">@EnableEurekaClient</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppOrder</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">SpringApplication.run(AppOrder.class, args);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="meta">@LoadBalanced</span></span><br><span class="line"><span class="function">RestTemplate <span class="title">restTemplate</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">new</span> RestTemplate();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>@LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力<br><img src="/images/springcloud/第2章/03.png" alt="SpringCloud"><br><img src="/images/springcloud/第2章/04.png" alt="SpringCloud"></p><h2 id="高可用注册中心"><a href="#高可用注册中心" class="headerlink" title="高可用注册中心"></a>高可用注册中心</h2><p>在微服务中,注册中心非常核心,可以实现服务治理,如果一旦注册出现故障的时候,可能会导致整个微服务无法访问,在这时候就需要对注册中心实现高可用集群模式。</p><h3 id="Eureka高可用原理"><a href="#Eureka高可用原理" class="headerlink" title="Eureka高可用原理"></a>Eureka高可用原理</h3><p>默认情况下Eureka是让服务注册中心,不注册自己<br></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 因为该应用为注册中心,不会注册自己</span></span><br><span class="line"><span class="attr">register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="comment">### 不需要去注册中心上检索服务</span></span><br><span class="line"><span class="attr">fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p></p><p>Eureka高可用实际上将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,从而实现服务清单的互相同步,达到高可用效果。</p><h3 id="Eureka集群环境搭建"><a href="#Eureka集群环境搭建" class="headerlink" title="Eureka集群环境搭建"></a>Eureka集群环境搭建</h3><h4 id="Eureka01配置"><a href="#Eureka01配置" class="headerlink" title="Eureka01配置"></a>Eureka01配置</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###服务端口号</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8100</span></span><br><span class="line"><span class="comment">###eureka 基本信息配置</span></span><br><span class="line"><span class="attr">spring:</span> </span><br><span class="line"><span class="attr"> application:</span> </span><br><span class="line"><span class="attr"> name:</span> <span class="string">eureka-server</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> instance:</span></span><br><span class="line"> <span class="comment">###注册到eurekaip地址</span></span><br><span class="line"><span class="attr"> hostname:</span> <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> serviceUrl:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://127.0.0.1:8200/eureka/</span></span><br><span class="line"><span class="comment">###因为自己是为注册中心,不需要自己注册自己</span></span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="comment">###因为自己是为注册中心,不需要检索服务</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="Eureka02配置"><a href="#Eureka02配置" class="headerlink" title="Eureka02配置"></a>Eureka02配置</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">###服务端口号</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8200</span></span><br><span class="line"><span class="comment">###eureka 基本信息配置</span></span><br><span class="line"><span class="attr">spring:</span> </span><br><span class="line"><span class="attr"> application:</span> </span><br><span class="line"><span class="attr"> name:</span> <span class="string">eureka-server</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> instance:</span></span><br><span class="line"> <span class="comment">###注册到eurekaip地址</span></span><br><span class="line"><span class="attr"> hostname:</span> <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> serviceUrl:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://127.0.0.1:8100/eureka/</span></span><br><span class="line"><span class="comment">### 因为自己是为注册中心,不需要自己注册自己</span></span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="comment">### 因为自己是为注册中心,不需要检索服务</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="客户端集成Eureka集群"><a href="#客户端集成Eureka集群" class="headerlink" title="客户端集成Eureka集群"></a>客户端集成Eureka集群</h4><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">server:</span></span><br><span class="line"><span class="attr"> port:</span> <span class="number">8000</span></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line"><span class="attr"> application:</span></span><br><span class="line"><span class="attr"> name:</span> <span class="string">app-itmayiedu-member</span></span><br><span class="line"><span class="comment">#eureka:</span></span><br><span class="line"><span class="comment"># client:</span></span><br><span class="line"><span class="comment"># service-url:</span></span><br><span class="line"><span class="comment"># defaultZone: http://localhost:8100/eureka</span></span><br><span class="line"><span class="comment">###集群地址</span></span><br><span class="line"><span class="attr">eureka:</span></span><br><span class="line"><span class="attr"> client:</span></span><br><span class="line"><span class="attr"> service-url:</span></span><br><span class="line"><span class="attr"> defaultZone:</span> <span class="attr">http://localhost:8100/eureka,http://localhost:8200/eureka</span> </span><br><span class="line"><span class="attr"> register-with-eureka:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr"> fetch-registry:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h4 id="Maven配置"><a href="#Maven配置" class="headerlink" title="Maven配置"></a>Maven配置</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>2.0.1.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 管理依赖 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-dependencies<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">version</span>&gt;</span>Finchley.M7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">type</span>&gt;</span>pom<span class="tag">&lt;/<span class="name">type</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">scope</span>&gt;</span>import<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencyManagement</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!--SpringCloud eureka-server --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.cloud<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-eureka-server<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 注意: 这里必须要添加, 否者各种依赖有问题 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">id</span>&gt;</span>spring-milestones<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">name</span>&gt;</span>Spring Milestones<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repo.spring.io/libs-milestone<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">enabled</span>&gt;</span>false<span class="tag">&lt;/<span class="name">enabled</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">snapshots</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="课程截图"><a href="#课程截图" class="headerlink" title="课程截图"></a>课程截图</h2><h3 id="rpc核心"><a href="#rpc核心" class="headerlink" title="rpc核心"></a>rpc核心</h3><p><img src="/images/springcloud/第2章/rpc核心.png" alt="SpringCloud"></p><h3 id="服务注册与发现原理"><a href="#服务注册与发现原理" class="headerlink" title="服务注册与发现原理"></a>服务注册与发现原理</h3><p><img src="/images/springcloud/第2章/服务注册与发现原理.png" alt="SpringCloud"></p><h3 id="注册中心原理"><a href="#注册中心原理" class="headerlink" title="注册中心原理"></a>注册中心原理</h3><p><img src="/images/springcloud/第2章/注册中心原理.png" alt="SpringCloud"></p><h3 id="负载均衡"><a href="#负载均衡" class="headerlink" title="负载均衡"></a>负载均衡</h3><p><img src="/images/springcloud/第2章/负载均衡.png" alt="SpringCloud"></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;什么是服务治理&quot;&gt;&lt;a href=&quot;#什么是服务治理&quot; class=&quot;headerlink&quot; title=&quot;什么是服务治理&quot;&gt;&lt;/a&gt;
</summary>
<category term="Spring Cloud" scheme="http://smartdot.club/categories/Spring-Cloud/"/>
<category term="Spring Cloud" scheme="http://smartdot.club/tags/Spring-Cloud/"/>
</entry>
<entry>
<title>第1章 网站架构演变过程</title>
<link href="http://smartdot.club/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%A1%86%E6%9E%B6/Spring%20Cloud/%E7%AC%AC1%E7%AB%A0%20%E7%BD%91%E7%AB%99%E6%9E%B6%E6%9E%84%E6%BC%94%E5%8F%98%E8%BF%87%E7%A8%8B/"/>
<id>http://smartdot.club/微服务框架/Spring Cloud/第1章 网站架构演变过程/</id>
<published>2019-03-10T12:17:09.000Z</published>
<updated>2019-03-13T04:02:06.398Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="传统项目架构-单点应用,SSH或者SSM架构"><a href="#传统项目架构-单点应用,SSH或者SSM架构" class="headerlink" title="传统项目架构(单点应用,SSH或者SSM架构)"></a>传统项目架构(单点应用,SSH或者SSM架构)</h2><p>传统的SSH架构,分为三层架构 web控制层、业务逻辑层、数据库访问层。<br>传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务没有进行拆分,都写同一个项目工程里面,一般是适合于个人或者是小团队开发。<br>这种架构模式,一旦有一个模块导致服务不可用,可能会影响整个项目。<br><img src="/images/springcloud/第1章/01.png" alt="SpringCloud"></p><h2 id="什么是项目集群"><a href="#什么是项目集群" class="headerlink" title="什么是项目集群"></a>什么是项目集群</h2><p>多台服务器部署相同应用构成一个集群<br>作用:通过负载均衡设备共同对外提供服务</p><h2 id="分布式项目架构"><a href="#分布式项目架构" class="headerlink" title="分布式项目架构"></a>分布式项目架构</h2><p>分布式架构基于传统架构演变过来,将传统的单体项目以项目模块进行拆分,拆分为会员项目、订单项目、支付项目、优惠券项目等,从而降低耦合度,这种项目架构模式慢慢开始适合于互联网公司规模人数开发。</p><h2 id="SOA架构"><a href="#SOA架构" class="headerlink" title="SOA架构"></a>SOA架构</h2><p>SOA架构代表面向与服务架构,俗称服务化,通俗的理解为面向与业务逻辑层开发,将共同的业务逻辑抽取出来形成一个服务,提供给其他服务接口进行调用,服务与服务之间调用使用rpc远程技术。<br>SOA架构特点:</p><ol><li>SOA架构中通常使用XML方式实现通讯,在高并发情况下XML比较冗余会带来极大的影响,所以最后微服务架构中采用JSON替代xml方式。</li><li>SOA架构的底层实现通过WebService和ESB(xml与中间件混合物),Web Service技术是SOA服务化的一种实现方式,WebService底层采用soap协议进行通讯,soap协议就是Http或者是Https通道传输XML数据实现的协议。</li></ol><h2 id="微服务架构"><a href="#微服务架构" class="headerlink" title="微服务架构"></a>微服务架构</h2><h3 id="微服务架构产生的原因"><a href="#微服务架构产生的原因" class="headerlink" title="微服务架构产生的原因"></a>微服务架构产生的原因</h3><p>微服务架构基于SOA架构演变过来的<br>在传统的WebService架构中有如下问题:</p><ol><li>依赖中心化服务发现机制</li><li>使用Soap通讯协议,通常使用XML格式来序列化通讯数据,xml格式非常喜欢重,比较占宽带传输。</li><li>服务化管理和治理设施不完善</li></ol><h3 id="漫谈微服务架构"><a href="#漫谈微服务架构" class="headerlink" title="漫谈微服务架构"></a>漫谈微服务架构</h3><h2 id="什么是微服务"><a href="#什么是微服务" class="headerlink" title="什么是微服务"></a>什么是微服务</h2><p>微服务架是从SOA架构演变过来,比SOA架构粒度会更加精细,让专业的人去做专业的事情(专注),目的提高效率,每个服务于服务之间互不影响,微服务架构中,每个服务必须独立部署,互不影响,微服务架构更加体现轻巧、轻量级,是适合于互联网公司敏捷开发。</p><h2 id="微服务架构特征"><a href="#微服务架构特征" class="headerlink" title="微服务架构特征"></a>微服务架构特征</h2><p>微服务架构倡导应用程序设计程多个独立、可配置、可运行和可微服务的子服务。<br>服务与服务通讯协议采用Http协议,使用restful风格API形式来进行通讯,数据交换格式轻量级json格式通讯,整个传输过程中,采用二进制,所以http协议可以跨语言平台,并且可以和其他不同的语言进行相互的通讯,所以很多开放平台都采用http协议接口。</p><h2 id="微服务架构如何拆分"><a href="#微服务架构如何拆分" class="headerlink" title="微服务架构如何拆分"></a>微服务架构如何拆分</h2><ol><li>微服务把每一个职责单一功能存放在独立的服务中</li><li>每个服务运行在单独的进程中</li><li>每个服务有自己独立数据库存储、实际上有自己独立的缓存、数据库、消息队列等资源。</li></ol><h2 id="微服务架构与SOA架构区别"><a href="#微服务架构与SOA架构区别" class="headerlink" title="微服务架构与SOA架构区别"></a>微服务架构与SOA架构区别</h2><ol><li>微服务架构基于SOA架构演变过来,继承SOA架构的优点,在微服务架构中去除SOA架构中的ESB 消息总线,采用 http+json(restful)进行传输。</li><li>微服务架构比 SOA 架构粒度会更加精细,让专业的人去做专业的事情(专注),目的提高效率,每个服务于服务之间互不影响,微服务架构中,每个服务必须独立部署,微服务架构更加轻巧,轻量级。</li><li>SOA 架构中可能数据库存储会发生共享,微服务强调独每个服务都是单独数据库,保证每个服务于服务之间互不影响。</li><li>项目体现特征微服务架构比 SOA 架构更加适合与互联网公司敏捷开发、快速迭代版本,因为粒度非常精细。</li></ol><h2 id="为什么选择SpringCloud"><a href="#为什么选择SpringCloud" class="headerlink" title="为什么选择SpringCloud"></a>为什么选择SpringCloud</h2><p>因为SpringCloud出现,对微服务技术提供了非常大的帮助,因为SpringCloud 提供了一套完整的微服务解决方案,不像其他框架只是解决了微服务中某个问题。<br>服务治理: 阿里巴巴开源的Dubbo和当当网在其基础上扩展的Dubbox、Eureka、Apache 的Consul等<br>分布式配置中心: 百度的disconf、Netfix的Archaius、360的QConf、SpringCloud、携程的阿波罗等。<br>分布式任务:xxl-job、elastic-job、springcloud的task等。<br>服务跟踪:京东的hyra、springcloud的sleuth等。</p><h2 id="SpringCloud简介"><a href="#SpringCloud简介" class="headerlink" title="SpringCloud简介"></a>SpringCloud简介</h2><p>SpringCloud是基于SpringBoot基础之上开发的微服务框架,SpringCloud是一套目前非常完整的微服务解决方案框架,其内容包含服务治理、注册中心、配置管理、断路器、智能路由、微代理、控制总线、全局锁、分布式会话等。<br>SpringCloud包含众多的子项目<br>SpringCloud config 分布式配置中心<br>SpringCloud netflix 核心组件<br>Eureka:服务治理 注册中心<br>Hystrix:服务保护框架<br>Ribbon:客户端负载均衡器<br>Feign:基于ribbon和hystrix的声明式服务调用组件<br>Zuul: 网关组件,提供智能路由、访问过滤等功能。<br><img src="/images/springcloud/第1章/02.png" alt="SpringCloud"></p><h2 id="课程截图"><a href="#课程截图" class="headerlink" title="课程截图"></a>课程截图</h2><h3 id="网站架构演变过程"><a href="#网站架构演变过程" class="headerlink" title="网站架构演变过程"></a>网站架构演变过程</h3><p><img src="/images/springcloud/第1章/网站架构演变过程.png" alt="网站架构演变过程"></p><h3 id="SOA"><a href="#SOA" class="headerlink" title="SOA"></a>SOA</h3><p><img src="/images/springcloud/第1章/SOA.png" alt="SOA"></p><h3 id="SOA架构-1"><a href="#SOA架构-1" class="headerlink" title="SOA架构"></a>SOA架构</h3><p><img src="/images/springcloud/第1章/SOA架构.png" alt="SOA架构"></p><h3 id="网站架构演变过程之分布式架构"><a href="#网站架构演变过程之分布式架构" class="headerlink" title="网站架构演变过程之分布式架构"></a>网站架构演变过程之分布式架构</h3><p><img src="/images/springcloud/第1章/网站架构演变过程之分布式架构.png" alt="网站架构演变过程之分布式架构"></p><h3 id="微服务架构产生的原因-1"><a href="#微服务架构产生的原因-1" class="headerlink" title="微服务架构产生的原因"></a>微服务架构产生的原因</h3><p><img src="/images/springcloud/第1章/微服务架构产生的原因.png" alt="微服务架构产生的原因"></p><h3 id="为什么要使用SpringCloud"><a href="#为什么要使用SpringCloud" class="headerlink" title="为什么要使用SpringCloud"></a>为什么要使用SpringCloud</h3><p><img src="/images/springcloud/第1章/为什么要使用SpringCloud.png" alt="为什么要使用SpringCloud"></p><h3 id="官方文档"><a href="#官方文档" class="headerlink" title="官方文档"></a>官方文档</h3><p><a href="https://springcloud.cc/spring-cloud-dalston.html" title="SpringCloud" target="_blank" rel="noopener">SpringCloud国内翻译文档: https://springcloud.cc/spring-cloud-dalston.html</a></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;传统项目架构-单点应用,SSH或者SSM架构&quot;&gt;&lt;a href=&quot;#传统项目架构-单点应用,SSH或者SSM架构&quot; class=&quot;he
</summary>
<category term="Spring Cloud" scheme="http://smartdot.club/categories/Spring-Cloud/"/>
<category term="Spring Cloud" scheme="http://smartdot.club/tags/Spring-Cloud/"/>
</entry>
<entry>
<title>Frp实现内网穿透</title>
<link href="http://smartdot.club/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/Frp%E5%AE%9E%E7%8E%B0%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
<id>http://smartdot.club/内网穿透/Frp实现内网穿透/</id>
<published>2019-03-06T14:17:09.000Z</published>
<updated>2019-03-12T15:30:59.338Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="内网穿透工具frp简易教程"><a href="#内网穿透工具frp简易教程" class="headerlink" title="内网穿透工具frp简易教程"></a>内网穿透工具frp简易教程</h2><p>如果你想把家里的电脑当做服务器用,做一个网站或者游戏服务器什么的,肯定会遇到一个问题:由于没有公网IP,而且有家里的路由器把关,导致其他地方的人完全无法连接到服务器。这时候就需要内网穿透和端口映射工具了,这样的工具有很多,我列举常用的几个:<br>1) 花生壳<br>2) nat123<br>3) ngrok<br>不过这几个工具虽然都算是挺好用的,但是都是收费的,虽然都有免费版,但是免费版功能实在太少,基本上只能绑定一个应用,端口号还是随机的。临时玩玩倒是可以,真正要用的话还是不行。经过一番寻找,最后我锁定了frp这个工具,它的优点就是完全开源免费,自定义配置;缺点是不提供服务,也就是说我们需要自己买个服务器在上面搭建。</p><h2 id="下载"><a href="#下载" class="headerlink" title="下载"></a>下载</h2><p>frp也是托管在Github上的开源项目,直接到Release页面下载即可,链接如下:<br><a href="https://github.com/fatedier/frp/releases" title="Frp" target="_blank" rel="noopener">https://github.com/fatedier/frp/releases</a><br><a href="https://diannaobos.com/frp/" title="Frp" target="_blank" rel="noopener">国内提供的二进制下载网站:https://diannaobos.com/frp/</a><br><img src="/images/frp/01.png" alt="Frp"><br>下载命令:<br></p><figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget http://diannaobos.iok.la:<span class="number">81</span>/frp/frp-v0<span class="meta">.20</span><span class="meta">.0</span>/frp_0<span class="meta">.20</span>.0_freebsd_amd64.tar.gz</span><br></pre></td></tr></table></figure><p></p><h2 id="Frp文件目录"><a href="#Frp文件目录" class="headerlink" title="Frp文件目录"></a>Frp文件目录</h2><p>Frp文件目录如下图所示:<br><img src="/images/frp/02.png" alt="Frp"><br>下载解压之后是一个文件夹,里面包含了frpc、frps可执行程序,以及它们对应的示例配置文件,前者是客户端程序,后者是服务端程序。运行frp需要同时运行客户端和服务端程序才行。full和min分别是最大和最小配置文件,如果需要参考的话可以打开看看,最大配置文件中列出了frp支持的所有选项。<br>注:Linux版本和Windows版本基本一致(windows下执行程序为frpc.exe,Linux下位frpc)。</p><h2 id="服务器端配置-frps-ini"><a href="#服务器端配置-frps-ini" class="headerlink" title="服务器端配置(frps.ini)"></a>服务器端配置(frps.ini)</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[common]</span></span><br><span class="line"><span class="attr">bind_port</span> = <span class="number">7000</span></span><br><span class="line"><span class="attr">token</span> = caifenglin</span><br><span class="line"><span class="comment"># vhost_http_port 网站访问端口</span></span><br><span class="line"><span class="attr">vhost_http_port</span> = <span class="number">8080</span></span><br></pre></td></tr></table></figure><p>bind_port是服务端与客户端之间通信使用的端口号,默认就可以。token用于验证连接,只有服务端和客户端token相同的时候才能正常访问。如果不使用token,那么所有人都可以直接连接上,所以我建议大家在使用的时候还是把token加上。</p><p>配置完毕后就可以启动服务器了,启动命令:<br></p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">frps</span> <span class="selector-tag">-c</span> <span class="selector-tag">frps</span><span class="selector-class">.ini</span></span><br></pre></td></tr></table></figure><p></p><h2 id="客户端配置-frpc-ini"><a href="#客户端配置-frpc-ini" class="headerlink" title="客户端配置(frpc.ini)"></a>客户端配置(frpc.ini)</h2><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[common]</span></span><br><span class="line"><span class="attr">server_addr</span> = <span class="number">118.25</span>.<span class="number">3.241</span></span><br><span class="line"><span class="attr">server_port</span> = <span class="number">7000</span></span><br><span class="line"><span class="attr">token</span> = caifenglin</span><br><span class="line"><span class="section">[web]</span></span><br><span class="line"><span class="comment"># 访问协议,如果需要https的话,只要把vhost_http_port改成vhost_https_port,再把客户端web下type设置为https即可。</span></span><br><span class="line"><span class="attr">type</span> = http</span><br><span class="line"><span class="comment"># 本地机器IP</span></span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="comment"># 本地机器端口</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">10000</span></span><br><span class="line"><span class="comment"># custom_domains是通过frp服务器端访问客户端的域名,必须输入完整的域名,</span></span><br><span class="line"><span class="comment"># 并且不能是subdomain_host的子域名,否则frp服务不能启动,并且相应的域名需要解析到frp服务器端的公网IP并等待解析生效后,才可以使用。</span></span><br><span class="line"><span class="attr">custom_domains</span> = springbook.cn</span><br></pre></td></tr></table></figure><p>windows启动命令:<br></p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">D</span>:\<span class="selector-tag">Frp</span>\<span class="selector-tag">frp_0</span><span class="selector-class">.20</span><span class="selector-class">.0_windows_amd64</span>&gt;<span class="selector-tag">frpc</span><span class="selector-class">.exe</span> <span class="selector-tag">-c</span> <span class="selector-tag">frpc</span><span class="selector-class">.ini</span></span><br></pre></td></tr></table></figure><p></p><p>至此,我们成功通过<a href="http//springbook.cn:8080" title="Frp">http//springbook.cn:8080</a>,访问<a href="http://127.0.0.1:10000" title="Frp" target="_blank" rel="noopener">http://127.0.0.1:10000</a>我本地局域网内的一个测试项目。</p><h2 id="仪表盘"><a href="#仪表盘" class="headerlink" title="仪表盘"></a>仪表盘</h2><p>frp还支持仪表盘功能,可以从网页查看运行的流量等信息。开启仪表盘需要在服务端进行设置。<br></p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># frps.ini</span></span><br><span class="line"><span class="section">[common]</span></span><br><span class="line"><span class="attr">dashboard_port</span> = <span class="number">7500</span></span><br><span class="line"><span class="comment"># dashboard 用户名密码,默认都为 admin</span></span><br><span class="line"><span class="attr">dashboard_user</span> = admin</span><br><span class="line"><span class="attr">dashboard_pwd</span> = admin</span><br></pre></td></tr></table></figure><p></p><p>设置完毕后,在浏览器中访问服务端地址:端口号并输入用户名与密码即可查看仪表盘。<br><img src="/images/frp/03.png" alt="Frp"><br>以上就是frp的一些介绍,如果有需要的请查看官方中文文档,详细列出了frp支持的各项功能,还可以参考frpc_full.ini与frps_full.ini,查看完整配置文件支持的选项。<a href="https://github.com/fatedier/frp/blob/master/README_zh.md" title="Frp" target="_blank" rel="noopener">文档地址:https://github.com/fatedier/frp/blob/master/README_zh.md</a>。</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;内网穿透工具frp简易教程&quot;&gt;&lt;a href=&quot;#内网穿透工具frp简易教程&quot; class=&quot;headerlink&quot; title=&quot;内
</summary>
<category term="内网穿透" scheme="http://smartdot.club/categories/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
<category term="内网穿透" scheme="http://smartdot.club/tags/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
</entry>
<entry>
<title>第5章 Jedis操作Redis</title>
<link href="http://smartdot.club/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E7%AC%AC5%E7%AB%A0%20Jedis%E6%93%8D%E4%BD%9CRedis/"/>
<id>http://smartdot.club/数据库/Redis/第5章 Jedis操作Redis/</id>
<published>2019-03-03T12:17:09.000Z</published>
<updated>2019-03-07T11:27:53.920Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="Jedis操作Redis"><a href="#Jedis操作Redis" class="headerlink" title="Jedis操作Redis"></a>Jedis操作Redis</h2><h3 id="下载Jedis和Commons-Pool"><a href="#下载Jedis和Commons-Pool" class="headerlink" title="下载Jedis和Commons-Pool"></a>下载Jedis和Commons-Pool</h3><h4 id="下载Jedis"><a href="#下载Jedis" class="headerlink" title="下载Jedis"></a>下载Jedis</h4><p>浏览器打开:<a href="http://search.maven.org/" title="jedis" target="_blank" rel="noopener">http://search.maven.org/</a>,搜索jedis,在Download处,点击jar<br><img src="/images/redis/redis191.png" alt="redis"></p><h4 id="下载Commons-Pool"><a href="#下载Commons-Pool" class="headerlink" title="下载Commons-Pool"></a>下载Commons-Pool</h4><p>Jedis对象并不是线程安全的,在多线程下使用同一个Jedis对象会出现并发问题。为了避免每次使用Jedis对象时都需要重新构建,Jedis提供了JedisPool。JedisPool是基于Commons Pool2实现的一个线程安全的连接池。<br>浏览器打开:<a href="http://search.maven.org/" title="commons-pool2" target="_blank" rel="noopener">http://search.maven.org/</a>,搜索commons-pool2,在Download处,点击jar<br><img src="/images/redis/redis192.png" alt="redis"></p><h3 id="Java应用使用Jedis准备"><a href="#Java应用使用Jedis准备" class="headerlink" title="Java应用使用Jedis准备"></a>Java应用使用Jedis准备</h3><p>项目中加入jar:</p><ul><li>jedis-3.0.1.jar</li><li>commons-pool2-2.6.1.jar</li><li>slf4j-api-1.7.26.jar(commons-pool2-2.6.1.jar依赖日志组件)<br>加入后如下图:<br><img src="/images/redis/redis193.png" alt="redis"><h4 id="字符串-string"><a href="#字符串-string" class="headerlink" title="字符串(string)"></a>字符串(string)</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.string;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisString</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">// 创建Jedis对象,连接到Redis,需要提供ip和port</span></span><br><span class="line">Jedis jedis = <span class="keyword">new</span> Jedis(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line"><span class="comment">// 添加字符串</span></span><br><span class="line">jedis.set(<span class="string">"breakfast"</span>, <span class="string">"豆浆和包子"</span>);</span><br><span class="line">String mybreak = jedis.get(<span class="string">"breakfast"</span>);</span><br><span class="line">System.out.println(<span class="string">"我的早餐1:"</span> + mybreak);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 追加内容</span></span><br><span class="line">jedis.append(<span class="string">"breakfast"</span>, <span class="string">"还有鸡蛋"</span>);</span><br><span class="line">mybreak = jedis.get(<span class="string">"breakfast"</span>);</span><br><span class="line">System.out.println(<span class="string">"我的早餐2:"</span> + mybreak);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 一次设置多个key-value</span></span><br><span class="line">jedis.mset(<span class="string">"lunch"</span>, <span class="string">"红烧肉"</span>, <span class="string">"dinner"</span>, <span class="string">"牛肉面"</span>);</span><br><span class="line"><span class="comment">// 获取多个key的value</span></span><br><span class="line">List&lt;String&gt; dinners = jedis.mget(<span class="string">"lunch"</span>, <span class="string">"dinner"</span>);</span><br><span class="line"><span class="keyword">for</span> (String dinner : dinners) &#123;</span><br><span class="line">System.out.println(<span class="string">"我吃的是"</span> + dinner);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul><h4 id="哈希-hash"><a href="#哈希-hash" class="headerlink" title="哈希(hash)"></a>哈希(hash)</h4><p>1) 使用Jedis连接实例池<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPoolConfig;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisUtil</span> </span>&#123;</span><br><span class="line"><span class="comment">// 定义连接池对象</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> JedisPool pool = <span class="keyword">null</span>;</span><br><span class="line"><span class="comment">// 创建连接池</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> JedisPool <span class="title">open</span><span class="params">(String host, <span class="keyword">int</span> port)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span>(pool == <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">// 使用JedisPool</span></span><br><span class="line">JedisPoolConfig config = <span class="keyword">new</span> JedisPoolConfig();</span><br><span class="line"><span class="comment">// 最大的Jedis实例数(连接池中是Jedis实例,默认是8)</span></span><br><span class="line">config.setMaxTotal(<span class="number">10</span>);</span><br><span class="line"><span class="comment">// 最大的空闲实例数,设置这个可以保留足够的连接,快速的获取到Jedis对象</span></span><br><span class="line">config.setMaxIdle(<span class="number">3</span>);</span><br><span class="line"><span class="comment">// 提前检查Jedis对象,为true获取的Jedis一定是可用的</span></span><br><span class="line">config.setTestOnBorrow(<span class="keyword">true</span>);</span><br><span class="line"><span class="comment">// 创建Jedis连接池,Redis没有访问密码时的使用方式</span></span><br><span class="line"><span class="comment">// pool = new JedisPool(config, host, port);</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 创建Jedis连接池,Redis有访问密码时的使用方式</span></span><br><span class="line"><span class="comment"> * 参数: JedisPoolCOnfig Redis的主机地址 端口 连接超时时间单位毫秒 访问密码</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">pool = <span class="keyword">new</span> JedisPool(config, host, port, <span class="number">60</span>*<span class="number">1000</span>, <span class="string">"caifenglin"</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> pool;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 关闭连接池</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">close</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span>(pool != <span class="keyword">null</span>) &#123;</span><br><span class="line">pool.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>2) 使用连接池操作hash数据类型<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.hash;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Iterator;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"><span class="keyword">import</span> java.util.Set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> club.smartdot.util.RedisUtil;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisHash</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">// 创建连接池</span></span><br><span class="line">JedisPool pool = RedisUtil.open(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line">Jedis jedis = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">// 从连接池中获取Jedis对象</span></span><br><span class="line">jedis = pool.getResource();</span><br><span class="line"><span class="comment">// 设置hash类型。key:loginuser, filed:username,value: zhangsan</span></span><br><span class="line">jedis.hset(<span class="string">"loginuser"</span>, <span class="string">"username"</span>, <span class="string">"zhangsan"</span>);</span><br><span class="line">System.out.println(<span class="string">"username的值:"</span> + jedis.hget(<span class="string">"loginuser"</span>, <span class="string">"username"</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 设置多个值</span></span><br><span class="line">Map&lt;String, String&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">map.put(<span class="string">"username"</span>, <span class="string">"caifenglin"</span>);</span><br><span class="line">map.put(<span class="string">"age"</span>, <span class="string">"26"</span>);</span><br><span class="line">map.put(<span class="string">"website"</span>, <span class="string">"www.smartdot.club"</span>);</span><br><span class="line">jedis.hmset(<span class="string">"logininfo"</span>, map);</span><br><span class="line"><span class="comment">// 从Redis取hash数据</span></span><br><span class="line">List&lt;String&gt; fieldValues = jedis.hmget(<span class="string">"logininfo"</span>, <span class="string">"username"</span>, <span class="string">"website"</span>);</span><br><span class="line"><span class="keyword">for</span> (String fv : fieldValues) &#123;</span><br><span class="line">System.out.println(<span class="string">"filed值:"</span> + fv);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 存在username吗?</span></span><br><span class="line">System.out.println(<span class="string">"返回boolean,存在username:"</span> + jedis.hexists(<span class="string">"logininfo"</span>, <span class="string">"username"</span>));</span><br><span class="line"><span class="comment">// 查看所有的field</span></span><br><span class="line">Set&lt;String&gt; set = jedis.hkeys(<span class="string">"logininfo"</span>);</span><br><span class="line">Iterator&lt;String&gt; iterator = set.iterator();</span><br><span class="line"><span class="keyword">while</span>(iterator.hasNext()) &#123;</span><br><span class="line">System.out.println(<span class="string">"field name:"</span> + iterator.next());</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 删除field:age</span></span><br><span class="line">jedis.hdel(<span class="string">"logininfo"</span>, <span class="string">"age"</span>);</span><br><span class="line"><span class="comment">// 获取age</span></span><br><span class="line">System.out.println(<span class="string">"age是null:"</span> + jedis.hget(<span class="string">"logininfo"</span>, <span class="string">"age"</span>));</span><br><span class="line"><span class="comment">// 所有field的数量</span></span><br><span class="line">System.out.println(<span class="string">"field个数:"</span> + jedis.hlen(<span class="string">"logininfo"</span>));</span><br><span class="line"></span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">e.printStackTrace();</span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line"><span class="keyword">if</span>(jedis != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">// 使用完的连接池对象,放回连接池</span></span><br><span class="line">jedis.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>运行结果<br></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SLF4J: Failed to <span class="keyword">load</span> <span class="keyword">class</span> <span class="string">"org.slf4j.impl.StaticLoggerBinder"</span>.</span><br><span class="line">SLF4J: Defaulting <span class="keyword">to</span> <span class="keyword">no</span>-operation (NOP) logger implementation</span><br><span class="line">SLF4J: See <span class="keyword">http</span>://www.slf4j.org/codes.html<span class="comment">#StaticLoggerBinder for further details.</span></span><br><span class="line">username的值:zhangsan</span><br><span class="line">filed值:caifenglin</span><br><span class="line">filed值:www.smartdot.club</span><br><span class="line">返回<span class="built_in">boolean</span>,存在username:<span class="literal">true</span></span><br><span class="line"><span class="keyword">field</span> <span class="keyword">name</span>:website</span><br><span class="line"><span class="keyword">field</span> <span class="keyword">name</span>:age</span><br><span class="line"><span class="keyword">field</span> <span class="keyword">name</span>:username</span><br><span class="line">age是<span class="literal">null</span>:<span class="literal">null</span></span><br><span class="line"><span class="keyword">field</span>个数:<span class="number">2</span></span><br></pre></td></tr></table></figure><p></p><h4 id="列表list"><a href="#列表list" class="headerlink" title="列表list"></a>列表list</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.list;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> club.smartdot.util.RedisUtil;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.ListPosition;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisList</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">JedisPool pool = RedisUtil.open(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line">Jedis jedis = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">// 从连接池中获取Jedis对象</span></span><br><span class="line">jedis = pool.getResource();</span><br><span class="line">String key = <span class="string">"framework"</span>;</span><br><span class="line">jedis.del(key);</span><br><span class="line">jedis.lpush(key, <span class="string">"mybatis"</span>);</span><br><span class="line">jedis.lpush(key, <span class="string">"hibernate"</span>, <span class="string">"spring"</span>, <span class="string">"springmvc"</span>);</span><br><span class="line">List&lt;String&gt; lists = jedis.lrange(key, <span class="number">0</span>, -<span class="number">1</span>);</span><br><span class="line"><span class="keyword">for</span> (String str : lists) &#123;</span><br><span class="line">System.out.println(<span class="string">"列表数据:"</span> + str);</span><br><span class="line">&#125;</span><br><span class="line">System.out.println(<span class="string">"列表长度:"</span> + jedis.llen(key));</span><br><span class="line">System.out.println(<span class="string">"插入新值后列表的长度:"</span> + jedis.linsert(key, ListPosition.AFTER, <span class="string">"spring"</span>, <span class="string">"jpa"</span>));</span><br><span class="line"><span class="comment">// 列表右侧插入数据</span></span><br><span class="line">jedis.rpush(key, <span class="string">"struts"</span>, <span class="string">"webwork"</span>);</span><br><span class="line">System.out.println(<span class="string">"列表数据:"</span> + jedis.lrange(key, <span class="number">0</span>, -<span class="number">1</span>));</span><br><span class="line">System.out.println(<span class="string">"第一个下标的值:"</span> + jedis.lindex(key, <span class="number">1</span>));</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">long</span> i = <span class="number">0</span>, len = jedis.llen(key); i &lt; len; i++) &#123;</span><br><span class="line">System.out.println(<span class="string">"弹出值:"</span> + jedis.lpop(key));</span><br><span class="line">&#125;</span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">e.printStackTrace();</span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line"><span class="keyword">if</span> (jedis != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">// 使用完的连接池对象,放回连接池</span></span><br><span class="line">jedis.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="集合set"><a href="#集合set" class="headerlink" title="集合set"></a>集合set</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Iterator;</span><br><span class="line"><span class="keyword">import</span> java.util.Set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> club.smartdot.util.RedisUtil;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisSet</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">JedisPool pool = RedisUtil.open(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line">Jedis jedis = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">// 从连接池中获取Jedis对象</span></span><br><span class="line">jedis = pool.getResource();</span><br><span class="line">String key = <span class="string">"course"</span>;</span><br><span class="line"><span class="comment">// 添加一个数据</span></span><br><span class="line">jedis.sadd(key, <span class="string">"html"</span>);</span><br><span class="line"><span class="comment">// 添加多个数据</span></span><br><span class="line">jedis.sadd(key, <span class="string">"css"</span>, <span class="string">"javascript"</span>, <span class="string">"jquery"</span>);</span><br><span class="line">Set&lt;String&gt; smembers = jedis.smembers(key);</span><br><span class="line">Iterator&lt;String&gt; iter = smembers.iterator();</span><br><span class="line"><span class="keyword">while</span>(iter.hasNext()) &#123;</span><br><span class="line">System.out.println(<span class="string">"集合成员:"</span> + iter.next());</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 判断spring是否在集合中</span></span><br><span class="line">System.out.println(<span class="string">"spring有吗?"</span> + jedis.sismember(key, <span class="string">"spring"</span>));</span><br><span class="line"><span class="comment">// 集合的成员数量</span></span><br><span class="line">System.out.println(<span class="string">"集合成员个数:"</span> + jedis.scard(key));</span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">e.printStackTrace();</span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line"><span class="keyword">if</span> (jedis != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">// 使用完的连接池对象,放回连接池</span></span><br><span class="line">jedis.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="有序集合sorted-set"><a href="#有序集合sorted-set" class="headerlink" title="有序集合sorted set"></a>有序集合sorted set</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.sort;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Iterator;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"><span class="keyword">import</span> java.util.Set;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> club.smartdot.util.RedisUtil;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Tuple;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisSortSet</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">JedisPool pool = RedisUtil.open(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line">Jedis jedis = <span class="keyword">null</span>;</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"><span class="comment">// 从连接池中获取Jedis对象</span></span><br><span class="line">jedis = pool.getResource();</span><br><span class="line">String key = <span class="string">"salary"</span>;</span><br><span class="line">jedis.zadd(key, <span class="number">2000</span>D, <span class="string">"John"</span>);</span><br><span class="line"><span class="comment">// 使用方法:zadd(String key, Map&lt;String, Double&gt;)添加多个数据</span></span><br><span class="line">Map&lt;String, Double&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">map.put(<span class="string">"Tom"</span>, <span class="number">3500</span>D);</span><br><span class="line">map.put(<span class="string">"Marry"</span>, <span class="number">6500</span>D);</span><br><span class="line">map.put(<span class="string">"Rose"</span>, <span class="number">3600</span>D);</span><br><span class="line">map.put(<span class="string">"Mike"</span>, <span class="number">5060</span>D);</span><br><span class="line"><span class="comment">// 添加多个数据</span></span><br><span class="line">jedis.zadd(key, map);</span><br><span class="line"><span class="comment">// 查询返回全部的数据,没有score</span></span><br><span class="line">Set&lt;String&gt; zrangeByScore3 = jedis.zrangeByScore(key, <span class="string">"-inf"</span>, <span class="string">"+inf"</span>);</span><br><span class="line">Set&lt;String&gt; zrangeByScore2 = zrangeByScore3;</span><br><span class="line">Set&lt;String&gt; zrangeByScore = zrangeByScore2;</span><br><span class="line">Set&lt;String&gt; sets = zrangeByScore;</span><br><span class="line">Iterator&lt;String&gt; iterator = sets.iterator();</span><br><span class="line"><span class="keyword">while</span>(iterator.hasNext()) &#123;</span><br><span class="line">System.out.println(<span class="string">"排序小-大的成员"</span> + iterator.next());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 带有score的数据</span></span><br><span class="line">Set&lt;Tuple&gt; tuple = jedis.zrangeByScoreWithScores(key, <span class="string">"-inf"</span>, <span class="string">"+inf"</span>);</span><br><span class="line">Iterator&lt;Tuple&gt; iters = tuple.iterator();</span><br><span class="line"><span class="keyword">while</span>(iters.hasNext()) &#123;</span><br><span class="line">Tuple tu = iters.next();</span><br><span class="line">System.out.println(<span class="string">"排序小-大的成员:"</span> + tu.getElement() + <span class="string">"# score:"</span> + tu.getScore());</span><br><span class="line">&#125;</span><br><span class="line">System.out.println(<span class="string">"有序集合成员数据量:"</span> + jedis.zcard(key));</span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">e.printStackTrace();</span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line"><span class="keyword">if</span> (jedis != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">// 使用完的连接池对象,放回连接池</span></span><br><span class="line">jedis.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="事物-Transaction"><a href="#事物-Transaction" class="headerlink" title="事物(Transaction)"></a>事物(Transaction)</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> club.smartdot.transcation;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> club.smartdot.util.RedisUtil;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Jedis;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.JedisPool;</span><br><span class="line"><span class="keyword">import</span> redis.clients.jedis.Transaction;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RedisTransaction</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">// 创建Jedis对象,连接到Redis, 需要提供ip和port</span></span><br><span class="line">JedisPool pool = RedisUtil.open(<span class="string">"127.0.0.1"</span>, <span class="number">6379</span>);</span><br><span class="line">Jedis jedis = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">jedis = pool.getResource();</span><br><span class="line"><span class="comment">//开启事物</span></span><br><span class="line">Transaction transaction = jedis.multi();</span><br><span class="line"><span class="comment">// 添加字符串</span></span><br><span class="line">transaction.mset(<span class="string">"breakfaset"</span>, <span class="string">"豆浆和包子"</span>);</span><br><span class="line"><span class="comment">// 一次设置多个key-value</span></span><br><span class="line">transaction.mset(<span class="string">"lunch"</span>, <span class="string">"红烧肉"</span>, <span class="string">"dinner"</span>, <span class="string">"牛肉面"</span>);</span><br><span class="line">List&lt;Object&gt; results = transaction.exec();</span><br><span class="line"><span class="comment">// 事物的处理结果</span></span><br><span class="line"><span class="keyword">for</span> (Object result : results) &#123;</span><br><span class="line">System.out.println(<span class="string">"成功的事物操作: "</span> + result);</span><br><span class="line">&#125;</span><br><span class="line">&#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">e.printStackTrace();</span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line"><span class="keyword">if</span>(jedis != <span class="keyword">null</span>) &#123;</span><br><span class="line">jedis.close();</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Jedis操作Redis&quot;&gt;&lt;a href=&quot;#Jedis操作Redis&quot; class=&quot;headerlink&quot; title=&quot;Jed
</summary>
<category term="数据库" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Redis" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/"/>
<category term="Redis" scheme="http://smartdot.club/tags/Redis/"/>
</entry>
<entry>
<title>第2章 Nginx应用</title>
<link href="http://smartdot.club/Nginx/%E7%AC%AC2%E7%AB%A0%20Nginx%E5%BA%94%E7%94%A8/"/>
<id>http://smartdot.club/Nginx/第2章 Nginx应用/</id>
<published>2019-03-02T14:17:09.000Z</published>
<updated>2019-03-12T06:09:54.847Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Nginx配置段详解"><a href="#Nginx配置段详解" class="headerlink" title="Nginx配置段详解"></a>Nginx配置段详解</h2><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 全局区</span></span><br><span class="line"><span class="comment">#user nobody;</span></span><br><span class="line"><span class="comment"># 有1个工作的子进程,可以自行修改,但太大无益,因为要争夺CPU</span></span><br><span class="line"><span class="comment"># 一般设置为CPU 数*核数</span></span><br><span class="line"><span class="attribute">worker_processes</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">#error_log logs/error.log;</span></span><br><span class="line"><span class="comment">#error_log logs/error.log notice;</span></span><br><span class="line"><span class="comment">#error_log logs/error.log info;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#pid logs/nginx.pid;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="section">events</span> &#123;</span><br><span class="line"><span class="comment"># 一般是配置Nginx连接的特性,如1个worker能同时允许多少连接</span></span><br><span class="line"><span class="comment"># 这是指一个子进程最大允许连接1024个连接。</span></span><br><span class="line"> <span class="attribute">worker_connections</span> <span class="number">1024</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 这是配置http服务器的主要部分</span></span><br><span class="line"><span class="section">http</span> &#123;</span><br><span class="line"> <span class="attribute">include</span> mime.types;</span><br><span class="line"> <span class="attribute">default_type</span> application/octet-stream;</span><br><span class="line"></span><br><span class="line"> <span class="comment">#log_format main '$remote_addr - $remote_user [$time_local] "$request" '</span></span><br><span class="line"> <span class="comment"># '$status $body_bytes_sent "$http_referer" '</span></span><br><span class="line"> <span class="comment"># '"$http_user_agent" "$http_x_forwarded_for"';</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">#access_log logs/access.log main;</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">sendfile</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="comment">#tcp_nopush on;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">#keepalive_timeout 0;</span></span><br><span class="line"> <span class="attribute">keepalive_timeout</span> <span class="number">65</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">#gzip on;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 这是配置虚拟主机部分</span></span><br><span class="line"> <span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"> <span class="attribute">server_name</span> localhost;</span><br><span class="line"></span><br><span class="line"> <span class="comment">#charset koi8-r;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">#access_log logs/host.access.log main;</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">root</span> html;</span><br><span class="line"> <span class="attribute">index</span> index.html index.htm;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">#error_page 404 /404.html;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># redirect server error pages to the static page /50x.html</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="attribute">error_page</span> <span class="number">500</span> <span class="number">502</span> <span class="number">503</span> <span class="number">504</span> /50x.html;</span><br><span class="line"> <span class="attribute">location</span> = /50x.html &#123;</span><br><span class="line"> <span class="attribute">root</span> html;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># proxy the PHP scripts to Apache listening on 127.0.0.1:80</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment">#location ~ \.php$ &#123;</span></span><br><span class="line"> <span class="comment"># proxy_pass http://127.0.0.1;</span></span><br><span class="line"> <span class="comment">#&#125;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment">#location ~ \.php$ &#123;</span></span><br><span class="line"> <span class="comment"># root html;</span></span><br><span class="line"> <span class="comment"># fastcgi_pass 127.0.0.1:9000;</span></span><br><span class="line"> <span class="comment"># fastcgi_index index.php;</span></span><br><span class="line"> <span class="comment"># fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;</span></span><br><span class="line"> <span class="comment"># include fastcgi_params;</span></span><br><span class="line"> <span class="comment">#&#125;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># deny access to .htaccess files, if Apache's document root</span></span><br><span class="line"> <span class="comment"># concurs with nginx's one</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment">#location ~ /\.ht &#123;</span></span><br><span class="line"> <span class="comment"># deny all;</span></span><br><span class="line"> <span class="comment">#&#125;</span></span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment"># another virtual host using mix of IP-, name-, and port-based configuration</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment">#server &#123;</span></span><br><span class="line"> <span class="comment"># listen 8000;</span></span><br><span class="line"> <span class="comment"># listen somename:8080;</span></span><br><span class="line"> <span class="comment"># server_name somename alias another.alias;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># location / &#123;</span></span><br><span class="line"> <span class="comment"># root html;</span></span><br><span class="line"> <span class="comment"># index index.html index.htm;</span></span><br><span class="line"> <span class="comment"># &#125;</span></span><br><span class="line"> <span class="comment">#&#125;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment"># HTTPS server</span></span><br><span class="line"> <span class="comment">#</span></span><br><span class="line"> <span class="comment">#server &#123;</span></span><br><span class="line"> <span class="comment"># listen 443 ssl;</span></span><br><span class="line"> <span class="comment"># server_name localhost;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># ssl_certificate cert.pem;</span></span><br><span class="line"> <span class="comment"># ssl_certificate_key cert.key;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># ssl_session_cache shared:SSL:1m;</span></span><br><span class="line"> <span class="comment"># ssl_session_timeout 5m;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># ssl_ciphers HIGH:!aNULL:!MD5;</span></span><br><span class="line"> <span class="comment"># ssl_prefer_server_ciphers on;</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># location / &#123;</span></span><br><span class="line"> <span class="comment"># root html;</span></span><br><span class="line"> <span class="comment"># index index.html index.htm;</span></span><br><span class="line"> <span class="comment"># &#125;</span></span><br><span class="line"> <span class="comment">#&#125;</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="Nginx配置虚拟主机"><a href="#Nginx配置虚拟主机" class="headerlink" title="Nginx配置虚拟主机"></a>Nginx配置虚拟主机</h2><p>例1:基于域名的虚拟主机<br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>; <span class="comment"># 监听端口</span></span><br><span class="line"> <span class="attribute">server_name</span> somename alias another.alias; <span class="comment"># 监听域名,如有多个,空格隔开</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">root</span> /var/www/website; <span class="comment"># 根目录定位</span></span><br><span class="line"> <span class="attribute">index</span> index.html index.htm; <span class="comment"># 默认索引页</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>例2:Apache的虚拟主机配置<br></p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">&lt;VirtualHost 192.168.137.201:80&gt;</span></span><br><span class="line"> <span class="attribute"><span class="nomarkup">DocumentRoot</span></span> <span class="string">"/var/www/website"</span></span><br><span class="line"> <span class="attribute"><span class="nomarkup">ServerName</span></span> www.website.com</span><br><span class="line"><span class="section">&lt;/VirtualHost&gt;</span></span><br></pre></td></tr></table></figure><p></p><p>例3: 基于端口的虚拟主机配置<br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">8080</span>; <span class="comment"># 监听端口</span></span><br><span class="line"> <span class="attribute">server_name</span> springbook.cn;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">root</span> /var/www/website; <span class="comment"># 根目录定位</span></span><br><span class="line"> <span class="attribute">index</span> index.html index.htm; <span class="comment"># 默认索引页</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h2 id="日志管理"><a href="#日志管理" class="headerlink" title="日志管理"></a>日志管理</h2><p>我们观察Nginx的server段可以看到如下类似信息<br>access_log logs/access.log main;</p><p>这说明该server,它的访问日志的文件是logs/host、access.log,<br>日志格式”main”格式</p><p>main格式是什么<br></p><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">#log_format main '<span class="variable">$remote_addr</span> - <span class="variable">$remote_user</span> [<span class="variable">$time_local</span>] <span class="string">"$request"</span> '</span><br><span class="line"># '<span class="variable">$status</span> <span class="variable">$body_bytes_sent</span> <span class="string">"$http_referer"</span> '</span><br><span class="line"># '<span class="string">"$http_user_agent"</span> <span class="string">"$http_x_forwarded_for"</span>';</span><br><span class="line"></span><br><span class="line">#access_log logs/access.<span class="keyword">log</span> main;</span><br></pre></td></tr></table></figure><p></p><p>除了main格式,你可以自定义其它格式<br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">log_format</span> mylog <span class="string">'<span class="variable">$remote_addr</span> [<span class="variable">$time_local</span>] "<span class="variable">$request</span>" '</span></span><br><span class="line"> <span class="string">'<span class="variable">$status</span> <span class="variable">$body_bytes_sent</span> "<span class="variable">$http_referer</span>" '</span></span><br><span class="line"> <span class="string">'"<span class="variable">$http_user_agent</span>"'</span>;</span><br></pre></td></tr></table></figure><p></p><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line"> listen <span class="number">80</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># 下面声明a.com使用mylog格式日志,并保存在logs/a.com.log文件中</span></span><br><span class="line"> access_log logs/a.com.<span class="built_in">log</span> mylog;</span><br><span class="line"> server_name springbook.cn;</span><br><span class="line"> ···</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>main格式是我们定义好一种日志的格式,并起个名字,便于引用。以上面的例子,main类型的日志记录的remote_addr···http_x_forwarded_for等选项。</p><p>日志格式:是指记录哪些选项<br>默认的日志格式: main<br></p><figure class="highlight cos"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">#log_format main '<span class="built_in">$remote</span>_addr - <span class="built_in">$remote</span>_user [<span class="built_in">$time</span>_local] <span class="string">"$request"</span> '</span><br><span class="line"># '<span class="built_in">$status</span> <span class="built_in">$body</span>_bytes_sent <span class="string">"$http_referer"</span> '</span><br><span class="line"># '<span class="string">"$http_user_agent"</span> <span class="string">"$http_x_forwarded_for"</span>'<span class="comment">;</span></span><br></pre></td></tr></table></figure><p></p><p>如默认的main日志格式,记录这么几项<br>远程IP 远程用户 用户时间 请求方法(如GET/POST) 请求体长度 referer来源信息 http-user-agent 用户代理/蜘蛛,被转发的请求的原始IP http_x_forwarded_for在经过代理时,代理把你的本来IP加在此头信息中,传输你的原始IP。<br>实际应用: Shell+定时任务+Nginx信号管理,完成日志按日期存储。</p><h2 id="PHP配置移植"><a href="#PHP配置移植" class="headerlink" title="PHP配置移植"></a>PHP配置移植</h2><p>略</p><h2 id="pathinfo支持"><a href="#pathinfo支持" class="headerlink" title="pathinfo支持"></a>pathinfo支持</h2><p>pathinfo类似于java开发中的restful风格<br></p><figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">典型配置</span><br><span class="line"><span class="keyword">location</span> <span class="title">~ \.php</span>$ &#123;</span><br><span class="line"> root html;</span><br><span class="line"> fastcgi_pass <span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">9000</span>;</span><br><span class="line"> fastcgi_index index.php;</span><br><span class="line"> fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;</span><br><span class="line"> include fastcgi_params;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改1,5,6行,支持pathinfo</span></span><br><span class="line"><span class="keyword">location</span> <span class="title">~ \.php</span>(.*) &#123; <span class="comment"># 正则匹配,php前后的script_name和pathinfo部分</span></span><br><span class="line"> root html;</span><br><span class="line"> fastcgi_pass <span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">9000</span>;</span><br><span class="line"> fastcgi_index index.php;</span><br><span class="line"> fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;</span><br><span class="line"> fastcgi_param PATH_<span class="literal">INF</span>O $<span class="number">1</span>; <span class="comment"># 把pathinfo部分赋值给PATH_INFO变量</span></span><br><span class="line"> include fastcgi_params;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h2 id="Nginx与Rewrite规则"><a href="#Nginx与Rewrite规则" class="headerlink" title="Nginx与Rewrite规则"></a>Nginx与Rewrite规则</h2><p>Rewrite语法<br>Rewrite正则表达式 定向后的位置 模式<br>Goods-3.html ——&gt; Goods.php?goods_id=$1<br></p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">goods-([\d+])\.html ---&gt; goods.php?<span class="attribute">goods_id</span>=<span class="variable">$1</span></span><br><span class="line"></span><br><span class="line">location / &#123;</span><br><span class="line">index index.php</span><br><span class="line">rewrite goods-([\d]+)\.html$ /ecshop/goods.php?<span class="attribute">id</span>=<span class="variable">$1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>注意:用url重写时,正则里如果有“{}”,正则要用双引号包起来。</p><h2 id="try-files"><a href="#try-files" class="headerlink" title="try_files"></a>try_files</h2><p>当用户请求 <a href="http://localhost/example" target="_blank" rel="noopener">http://localhost/example</a> 时,这里的 $uri 就是 /example。<br>try_files 会到硬盘里尝试找这个文件。如果存在名为 /$root/example(其中 $root 是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户。<br>显然,目录中没有叫 example 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 /$root/example/ 的目录。<br>又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 <a href="http://localhost/index.php。" target="_blank" rel="noopener">http://localhost/index.php。</a><br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> / &#123;</span><br><span class="line"><span class="attribute">try_files</span> <span class="variable">$uri</span> /index.php?<span class="variable">$uri</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>try_files方法让Ngxin尝试访问后面得$uri链接,并进根据@apache配置进行内部重定向。</p><p>当然try_files也可以以错误代码赋值,如try_files /index.php = 404 @apache,则表示当尝试访问得文件返回404时,根据@apache配置项进行重定向。</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Nginx配置段详解&quot;&gt;&lt;a href=&quot;#Nginx配置段详解&quot; class=&quot;headerlink&quot; title=&quot;Nginx配置
</summary>
<category term="Nginx" scheme="http://smartdot.club/categories/Nginx/"/>
<category term="Nginx" scheme="http://smartdot.club/tags/Nginx/"/>
</entry>
<entry>
<title>第3章 Nginx优化</title>
<link href="http://smartdot.club/Nginx/%E7%AC%AC3%E7%AB%A0%20Nginx%E4%BC%98%E5%8C%96/"/>
<id>http://smartdot.club/Nginx/第3章 Nginx优化/</id>
<published>2019-03-02T14:17:09.000Z</published>
<updated>2019-03-12T07:05:01.048Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Nginx反向代理与动静分离"><a href="#Nginx反向代理与动静分离" class="headerlink" title="Nginx反向代理与动静分离"></a>Nginx反向代理与动静分离</h2><p>用nginx做反向代理用proxy_pass,以反向代理为例,nginx不自己处理图片的相关请求,而是把图片的请求转发给apache来处理。<br><img src="/images/nginx/04.png" alt="Nginx"><br>—这就是传说的“动静分离”,动静分离不是一个严谨的说法,叫反向代理比较规范。<br>配置如下:<br></p><figure class="highlight coq"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">location ~ \.(jpg|<span class="type">jpeg</span>|<span class="type">png</span>|<span class="type">gif</span>)$ &#123;</span><br><span class="line">proxy_pass HTTP://IP:PORT;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>思考:</p><ol><li><p>反向代理导致了后端服务器接到的客户端IP为前端服务器的IP,而不是客户真正的IP,怎么办?<br>答: 代理服务器通过设置头信息字段,把用户的IP传递到后台服务器去。<br>如:</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> <span class="regexp">~ \.(jpg|jpeg|png|gif)$</span> &#123;</span><br><span class="line"><span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$remote_addr</span>;</span><br><span class="line"><span class="attribute">proxy_pass</span> HTTP://IP:PORT;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>在apache的日志格式里加上X-Forwarded-For,如下:</p><figure class="highlight perl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LogFormat <span class="string">"%&#123;X-Forwarded-For&#125;i %l %u \"%r\" %&gt;s %b"</span> common</span><br></pre></td></tr></table></figure></li><li><p>如果后端的服务器非常多,该如何写?又如何均匀的分发任务?(负载均衡)</p></li></ol><h2 id="Nginx集群和负载均衡"><a href="#Nginx集群和负载均衡" class="headerlink" title="Nginx集群和负载均衡"></a>Nginx集群和负载均衡</h2><p>具体的负载均衡的方式<br>注意:负载均衡是一种方案,实现办法有DNS轮询。<br>如下图,DNS服务器允许一个域名有多个A记录。那么在用户访问时,一般按地域返回一个较近的解析记录。这样,全国不同的地区,看到的163的主页,来自不同的服务器。<br><img src="/images/nginx/05.png" alt="Nginx"></p><p>第二步:当解析出结果,比如浏览器连接60.217时,这台主机后面还有N台,也要做负载均衡。<br>1) 硬件上做负载均衡,F5 BIG-IP,硬件负载均衡(很贵)直接从TCP/IP的底层协议上,直接做数据包的中转。<br>2) 软件负载均衡,LVS<br>3) 反向代理+负载均衡<br>在nignx中做集群与负载均衡步骤都是一样的,Upstream{}模块把多台服务器加入到一个组,然后memcached_pass,fastcgi_pass, proxy_pass ==&gt; upstream组<br>具体配置步骤:<br>配置upstream<br></p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">upstream imageserver &#123;</span><br><span class="line"><span class="built_in">server </span>192.168.1.204:8080 <span class="attribute">weight</span>=1 <span class="attribute">max_fails</span>=2 <span class="attribute">fail_timeout</span>=30s;</span><br><span class="line"><span class="built_in">server </span>192.168.1.204:8081 <span class="attribute">weight</span>=1 <span class="attribute">max_fails</span>=2 <span class="attribute">fail_timeout</span>=30s;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>下游调用:<br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> <span class="regexp">~ \.(jpg|jpeg|png|gif)$</span> &#123;</span><br><span class="line"><span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$remote_addr</span>;</span><br><span class="line"><span class="attribute">proxy_pass</span> http://imageserver;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>默认的负载均衡算的算法:<br>是设置计数器,轮流请求N台服务器</p><p>可以按照第3中模式,来利用不同参数把请求均衡到不同服务器去,<br>如基于cookie值区别用户做负载均衡(nginx sticky模块),<br>或基于URI利用一致性哈希算法做均衡(NginxHttpUpstreamConsistentHash模块)<br>或基于IP做负载均衡等。</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Nginx反向代理与动静分离&quot;&gt;&lt;a href=&quot;#Nginx反向代理与动静分离&quot; class=&quot;headerlink&quot; title=
</summary>
<category term="Nginx" scheme="http://smartdot.club/categories/Nginx/"/>
<category term="Nginx" scheme="http://smartdot.club/tags/Nginx/"/>
</entry>
<entry>
<title>第4章 高级话题</title>
<link href="http://smartdot.club/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E7%AC%AC4%E7%AB%A0%20%E9%AB%98%E7%BA%A7%E8%AF%9D%E9%A2%98/"/>
<id>http://smartdot.club/数据库/Redis/第4章 高级话题/</id>
<published>2019-03-02T12:17:09.000Z</published>
<updated>2019-03-07T08:42:54.846Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h3 id="Redis事物"><a href="#Redis事物" class="headerlink" title="Redis事物"></a>Redis事物</h3><h4 id="什么是事物"><a href="#什么是事物" class="headerlink" title="什么是事物"></a>什么是事物</h4><p>事物是指一系列操作步骤,这一系列的操作步骤,要么完全地执行,要么完全地不执行。<br>Redis中的事物(transaction)是一组命令的集合,至少是两个或两个以上的命令,redis事物保证这些命令被执行时中间不会被任何其他操作打断。</p><h4 id="事物操作的命令"><a href="#事物操作的命令" class="headerlink" title="事物操作的命令"></a>事物操作的命令</h4><h5 id="multi"><a href="#multi" class="headerlink" title="multi"></a>multi</h5><p>语法: multi<br>作用: 标记一个事物的开始。事物内的多条命令会按照先后顺序被放到一个队列当中。<br>返回值: 总是返回OK</p><h5 id="exec"><a href="#exec" class="headerlink" title="exec"></a>exec</h5><p>语法: exec<br>作用: 执行所有事物块内的命令<br>返回值: 事物内的所有执行语句内容,事物被打断(影响)返回nil</p><h5 id="discard"><a href="#discard" class="headerlink" title="discard"></a>discard</h5><p>语法: discard<br>作用: 取消事物,放弃执行事物块内的所有命令<br>返回值: 总是返回OK</p><h5 id="watch"><a href="#watch" class="headerlink" title="watch"></a>watch</h5><p>语法: watch key [key···]<br>作用: 监视一个(或多个)key,如果在事物执行之前这个(或这些)key被其他命令所改动,那么事物将被打断。<br>返回值: 总是返回OK</p><h5 id="unwatch"><a href="#unwatch" class="headerlink" title="unwatch"></a>unwatch</h5><p>语法: unwatch<br>作用: 取消WATCH命令对所有key的监视。如果在执行WATCH命令之后,EXEC命令或DISCARD命令先被执行了的话,那么就不需要在执行UNWATCH了<br>返回值: 总是返回OK</p><h4 id="事物的实现"><a href="#事物的实现" class="headerlink" title="事物的实现"></a>事物的实现</h4><h5 id="正常执行事物"><a href="#正常执行事物" class="headerlink" title="正常执行事物"></a>正常执行事物</h5><p>事物的执行步骤: 首先开启事物,其次向事物队列中加入命令,最后执行事物提交。<br>例1: 事物的执行:<br>1) multi:用multi命令告诉Redis,接下来要执行的命令你先不要执行,而是把它们暂时存起来(开启事物)<br>2) sadd works john 第一条命令进入等待队列(命令入队)<br>3) sadd works rose 第二条命令进入等待队列(命令入队)<br>4) exce 告知redis执行前面发送的两条命令(提交事物)<br><img src="/images/redis/redis123.png" alt="Redis"><br>查看works集合<br><img src="/images/redis/redis124.png" alt="Redis"></p><h5 id="事物执行exec之前,入队命令错误-语法错误;严重错误导致服务器不能正常工作-例如内存不足-放弃事物。"><a href="#事物执行exec之前,入队命令错误-语法错误;严重错误导致服务器不能正常工作-例如内存不足-放弃事物。" class="headerlink" title="事物执行exec之前,入队命令错误(语法错误;严重错误导致服务器不能正常工作(例如内存不足)),放弃事物。"></a>事物执行exec之前,入队命令错误(语法错误;严重错误导致服务器不能正常工作(例如内存不足)),放弃事物。</h5><p>执行事物步骤:<br>1) MULTI 正常命令<br>2) SET key value 正常命令<br>3) INCR 命令语法错误<br>4) EXEC 无法执行事物,那么第一条正确的命令也不会执行,所有key的值不会设置成功。<br><img src="/images/redis/redis125.png" alt="Redis"><br>结论: 事物执行exec之前,入队命令错误,事物终止,取消,不执行。</p><h5 id="事物执行exec命令后,执行队列命令,命令执行错误,事物提交"><a href="#事物执行exec命令后,执行队列命令,命令执行错误,事物提交" class="headerlink" title="事物执行exec命令后,执行队列命令,命令执行错误,事物提交"></a>事物执行exec命令后,执行队列命令,命令执行错误,事物提交</h5><p>执行步骤:<br>1) MULTI 正常命令<br>2) SET username zhangsan 正常命令<br>3) lpop username 正常命令,语法没有错误,执行命令时才会有错误<br>4) EXEC正常执行,发现错误可以在事物提交前放弃事物,执行discard<br><img src="/images/redis/redis126.png" alt="Redis"><br>结论: 在exec执行后的所产生的错误,即使事物中有某个/某些命令在执行时产生了错误,事物中的其他命令仍然会继续执行。</p><p>Redis在事物失败时不进行回滚,而是继续执行余下的命令。</p><p>Redis这种设计原则是: Redis命令只会因为错误的语法而失败(这些问题不能在入队时发现),或是命令用在了错误类型的键上面,失败的命令并不是Redis导致,而是由编程错误造成的,这样的错误还应该在开发中被发现,生产环境中不应出现语法的错误。就是在程序的运行环境中不应该出现语法的错误。而Redis能够保证正确的命令一定会被执行。再者不需要对回滚进行支持,所以Redis的内部可以保持简单且快速。</p><h5 id="放弃事物"><a href="#放弃事物" class="headerlink" title="放弃事物"></a>放弃事物</h5><p>1) MULTI开启事物<br>2) SET age 35 命令入队<br>3) SET age 30 命令入队<br>4) DISCARD 放弃事物,则命令队列不会被执行<br>例1:<br><img src="/images/redis/redis127.png" alt="Redis"></p><h5 id="Redis的watch机制"><a href="#Redis的watch机制" class="headerlink" title="Redis的watch机制"></a>Redis的watch机制</h5><h6 id="Redis的WATCH机制"><a href="#Redis的WATCH机制" class="headerlink" title="Redis的WATCH机制"></a>Redis的WATCH机制</h6><p>WATCH机制原理:<br>WATCH机制: 使用WATCH监视一个或多个key,跟踪key的value修改情况,如果有ley的value值在事物EXEC执行之前被修改了,整个事物被取消。EXEC返回提示信息,表示事物已经失败。</p><p>WATCH机制使的事物EXEC变得有条件,事物只有在被WATCH的key没有修改的前提下才能执行。不满足条件,事物被取消。使用WATCH监视了一个带过期时间的键,那么即使这个键过期了,事物任然可以正常执行。</p><p>大多数情况下,不同的客户端会访问不同的键,相互同时竞争同一key的情况一般都很少,乐观锁能够以很好的性能解决数据冲突的问题。</p><h6 id="何时取消key的监视-WATCH"><a href="#何时取消key的监视-WATCH" class="headerlink" title="何时取消key的监视(WATCH)?"></a>何时取消key的监视(WATCH)?</h6><p>1) WATCH命令可以被调用多次。对键的监视从WATCH执行之后开始生效,直到调用EXEC为止。不管事物是否成功执行,对所有键的监视都会被取消。<br>2) 当客户端断开连接时,该客户端对键的监视也会被取消。<br>3) UNWATCH命令可以手动取消对所有键的监视。</p><h6 id="WATCH的事例"><a href="#WATCH的事例" class="headerlink" title="WATCH的事例"></a>WATCH的事例</h6><p>执行步骤:<br>首先启动redis-server,在看起两个客户端连接。分别叫A客户端和B客户端。<br>启动Redis服务器<br><img src="/images/redis/redis128.png" alt="Redis"><br>A客户端(红色): WATCH某个key,同时执行事务<br><img src="/images/redis/redis129.png" alt="Redis"><br>B客户端(黄色): 对A客户端WATCH的key修改其value值。<br><img src="/images/redis/redis130.png" alt="Redis"></p><p>1) 在A客户端设置key:str.lp登录人数为10<br>2) 在A客户端监视key:str.lp<br>3) 在A客户端开启事物 multi<br>4) 在A客户端修改 str.lp的值为11<br>5) 在B客户端修改 str.lp的值为15<br>6) 在A客户端执行事物 exec<br>7) 在A客户端查看 str.lp的值,A客户端执行的事物没有提交,因为WATCH的str.lp的值已经被修改了,所以放弃事物。</p><p>例1: 乐观锁<br><img src="/images/redis/redis131.png" alt="Redis"></p><h3 id="持久化"><a href="#持久化" class="headerlink" title="持久化"></a>持久化</h3><h4 id="持久化概述"><a href="#持久化概述" class="headerlink" title="持久化概述"></a>持久化概述</h4><p>持久化可以理解为存储,就是将数据存储到一个不会丢失的地方,如果把数据放在内存中,电脑关闭或重启数据就会丢失,所以放在内存中的数据不是持久化的,而放在磁盘就算是一种持久化。</p><p>Redis的数据存储在内存中,内存是顺势的,如果linux宕机或重启,又或者Redis崩溃或重启,所有的内存数据都会丢失,为解决这个问题,Redis提供两种机制对数据进行持久化存储,便于发生故障后能迅速恢复数据。</p><h4 id="持久化方式"><a href="#持久化方式" class="headerlink" title="持久化方式"></a>持久化方式</h4><h5 id="RDB方式"><a href="#RDB方式" class="headerlink" title="RDB方式"></a>RDB方式</h5><h6 id="什么是RDB方式"><a href="#什么是RDB方式" class="headerlink" title="什么是RDB方式?"></a>什么是RDB方式?</h6><p>Redis Database(RDB),就是在指定的时间间隔内将内存中的数据集快照写入磁盘,数据恢复时将快照文件直接再读到内存。<br>RDB保存了在某个时间点的数据集(全部数据)。存储在一个二进制文件中,只有一个文件。默认是dump.rdb。RDB技术非常适合做备份,可以保存最近一个小时,一天,一个月的全部数据。保存数据是在单独的进程中写文件,不影响Redis的正常使用。RDB恢复数据时比其他AOF速度快。</p><h6 id="如何实现"><a href="#如何实现" class="headerlink" title="如何实现?"></a>如何实现?</h6><p>RDB方式的数据持久化,仅需在redis.conf文件中配置即可,默认配置是启用的。<br>在配置文件redis.conf中搜索SNAPSHOTTING,查找在注释开始和结束文件的关于RDB的配置说明。配置SNAPSHOTTING的地方有三处。<br>1) 配置执行RDB生成快照文件的时间策略。<br>对Redis进行设置,让它在“N秒内数据集至少有M个key改动”这一条件被满足时,自动保存一次数据集。<br>配置格式: save &lt;seconds> &lt;changes><br>save 900 1<br>save 300 10<br>save 60 10000<br>2) dbfilename: 设置RDB的文件名,默认文件名为dump.rdb<br>3) dir: 指定RDB文件的存储位置,默认是./当前目录</p><p>配置步骤:<br>1) 查看ps -ef | grep redis, 如果服务启动,先停止。<br>2) 修改redis.conf文件,修改前先备份,执行cp redis.conf redis.conf.bak<br>查看默认启用的RDB文件<br><img src="/images/redis/redis132.png" alt="Redis"><br>3) 编辑redis.conf增加save配置,修改文件名等。vim redis.conf<br><img src="/images/redis/redis133.png" alt="Redis"><br>修改的内容:<br><img src="/images/redis/redis134.png" alt="Redis"><br><img src="/images/redis/redis135.png" alt="Redis"><br>把原来的默认的dump.rdb删除,修改redis.conf后,重新启动redis<br>4) 在20秒内修改三个key的值<br><img src="/images/redis/redis136.png" alt="Redis"><br>5) 查看生成的rdb文件<br><img src="/images/redis/redis137.png" alt="Redis"></p><h6 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h6><p>优点: 由于存储的是数据快照文件,恢复数据很方便,也比较快<br>缺点:<br>1) 会丢失最后一次快照以后更改的数据。如果你的应用能容忍一定数据的丢失,那么使用rdb是不错的选择;如果你不能容忍一定数据的丢失,使用rdb就不是一个很好的选择。<br>2) 由于需要经常操作磁盘,RDB会分出一个子进程。如果你的reids数据库很大的话,子进程占用比较多的时间,并且可能会影响Redis暂停服务一段时间(millisecond级别),如果你的数据库超级大并且你的服务器CPU比较弱,有可能是会达到一秒。</p><h5 id="AOF方式"><a href="#AOF方式" class="headerlink" title="AOF方式"></a>AOF方式</h5><h6 id="什么是AOF方式"><a href="#什么是AOF方式" class="headerlink" title="什么是AOF方式"></a>什么是AOF方式</h6><p>Append-only File(AOF),Redis每次接受到一条改变数据的命令是,它将把该命令写到一个AOF文件中(只记录写操作,读操作不记录),当Redis重启时,它通过执行AOF文件中所有的命令来恢复数据。</p><h6 id="如何实现-1"><a href="#如何实现-1" class="headerlink" title="如何实现"></a>如何实现</h6><p>AOF方式的数据持久化,仅需在redis.conf文件中配置即可<br>配置项:<br>1) appendonly: 默认是no,改成yes即开启了aof持久化<br>2) appendfilename: 指定AOF文件名,默认文件名为:appendonly.aof<br>3) dir: 指定RDB和AOF文件存放的目录,默认是./<br>4) appendfsync: 配置向aof文件写命令数据的策略:<br>no: 不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),比较快但不是很安全。<br>always: 每次执行写入都会执行同步,慢一些但是比较安全。<br>everysec: 每秒执行一次同步操作,比较平衡,介于速度和安全之间。这是默认项。<br>5) auto-aof-rewrite-min-size: 允许重写的最小AOF文件大小,默认是64M。当aof文件大于64M时,开始整理aop文件,去掉无用的操作命令。缩小aop文件。</p><p>例1:<br>1) 停止运行的reids,备份要修改的redis.conf<br>2) 查看redis安装目录/src下有无.aof文件。默认是在redis的当前目录<br><img src="/images/redis/redis138.png" alt="Redis"><br>3) 编辑redis.conf<br>设置appendonly为yes即可。<br>查看appendfsync的当前策略。<br>查看appendfilename的文件名称。<br><img src="/images/redis/redis139.png" alt="Redis"><br><img src="/images/redis/redis140.png" alt="Redis"><br>4) 在redis客户端执行 写入命令<br><img src="/images/redis/redis141.png" alt="Redis"><br>5) 查看aof文件<br><img src="/images/redis/redis142.png" alt="Redis"><br><img src="/images/redis/redis143.png" alt="Redis"></p><h6 id="总结-1"><a href="#总结-1" class="headerlink" title="总结"></a>总结</h6><p>1) append-only文件是另一个可以提供完全数据保障的方案<br>2) AOF文件会在操作过程中变得越来越大。比如,如果你做一百次加法计算,最后你只会在数据库里面得到最终的数值,但是在你的AOF里面会存在100次记录,其中99条记录对最终的结果都是无用的;但Redis支持在不影响服务的前提下在后台重构AOF文件,让文件得以整理变小。<br>3) 可以同时使用这两种当时,redis默认优先加载aof文件(aof数据最完整);</p><h3 id="主从复制"><a href="#主从复制" class="headerlink" title="主从复制"></a>主从复制</h3><h4 id="主从复制–读写分离"><a href="#主从复制–读写分离" class="headerlink" title="主从复制–读写分离"></a>主从复制–读写分离</h4><p>通过持久化功能,Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,但是由于数据是存储在一台服务器上的,如果这台服务器出现故障,比如硬盘坏了,也会导致数据丢失。<br>为了避免单点故障,我们需要将数据复制多份部署在多台不同的服务器上,即使有一台服务器出现故障其他扶我去依然可以继续提供服务。<br>这就要求当一台服务器上的数据更新后,自动将更新的数据同步到其他服务器上,那该怎么实现呢?Redis的主从复制。<br><img src="/images/redis/redis144.png" alt="Redis"><br>Redis提供了复制(replication)功能来自动实现多台redis服务器的数据同步(每天19点新闻联播,基本从cctv1-8,各大卫视都会播放)<br>我们可以通过部署多台redis,并在配置文件中指定这几台redis之间的主从关系,主负责写入数据,同时把写入的数据实时同步到从机器,这种模式叫做主从复制,即master/slave,并且redis默认master用于写,slave用于读,向slave写数据会导致错误。</p><h5 id="Redis主从复制实现-master-salve"><a href="#Redis主从复制实现-master-salve" class="headerlink" title="Redis主从复制实现(master/salve)"></a>Redis主从复制实现(master/salve)</h5><p>方式1: 修改配置文件,启动时,服务器读取配置文件,并自动成为指定服务器的从服务器,从而构成主从复制的关系。<br>方式2: ./redis-server -slaveof &lt;master-ip> &lt;master-port>,在启动redis时指定当前服务成为某个主Redis服务器的从Slave。</p><p>方式1的实现步骤:<br>模拟多Redis服务器,在一台已经安装Redis的机器上,运行多个Redis应用模拟多个Redis服务器。一个Master,两个Slave。</p><h6 id="新建三个Redis的配置文件"><a href="#新建三个Redis的配置文件" class="headerlink" title="新建三个Redis的配置文件"></a>新建三个Redis的配置文件</h6><p>如果Redis启动,先停止。<br>作为Master的Redis端口是6380<br>作为Slave的Redis端口分别是6382,6384<br>从原有的redis.conf拷贝三份,分别命名为redis6380.conf,redis6382.conf, redis6384.conf<br><img src="/images/redis/redis145.png" alt="Redis"></p><h6 id="编辑Master配置文件"><a href="#编辑Master配置文件" class="headerlink" title="编辑Master配置文件"></a>编辑Master配置文件</h6><p>编辑Master的配置文件redis6380.conf: 在空文件加入如下内容<br>include /usr/local/redis-3.2.9/redis.conf<br>daemonize yes<br>port 6380<br>pidfile /var/run/redis_6380.pid<br>logfile 6380.log<br>dbfilename dump6380.rdb</p><p>配置项说明:<br>include: 包含原来的配置文件内容。/usr/local/redis-3.3.9/redis.conf按照自己的目录设置。<br>daemonize: yes 后台启动应用,相当于./redis-server &amp;, &amp;的作用。<br>port: 自定义的端口号<br>pidfile: 自定义的文件,表示当前程序的pid,进程id。<br>logfile: 日志文件<br>dbfilename: 持久化的rdb文件名</p><h6 id="编辑Slave配置文件"><a href="#编辑Slave配置文件" class="headerlink" title="编辑Slave配置文件"></a>编辑Slave配置文件</h6><p>编辑Slave的配置文件redis6382.conf和redis6384.conf: 在空文件加入如下内容<br>1) redis6382.conf:<br>include /usr/local/redis-3.2.9/redis.conf<br>daemonize yes<br>port 6382<br>pidfile /var/run/redis_6382.pid<br>logfile 6382.log<br>dbfilename dump6382.rdb<br>slaveof 127.0.0.1 6380</p><p>配置项说明:<br>slaveof: 表示当前Redis是谁的从。当前是127.0.0.1 端口是6380这个Master的从。</p><p>2) redis6384.conf:<br>include /usr/local/redis-3.2.9/redis.conf<br>daemonize yes<br>port 6384<br>pidfile /var/run/redis_6384.pid<br>logfile 6384.log<br>dbfilename dump6384.rdb<br>slaveof 127.0.0.1 6380</p><h6 id="启动服务器-Master-Slave都启动"><a href="#启动服务器-Master-Slave都启动" class="headerlink" title="启动服务器 Master/Slave都启动"></a>启动服务器 Master/Slave都启动</h6><p>启动方式 ./redis-server 配置文件<br>启动Redis,并查看启动进程<br><img src="/images/redis/redis146.png" alt="Redis"></p><h6 id="查看配置后的服务信息"><a href="#查看配置后的服务信息" class="headerlink" title="查看配置后的服务信息"></a>查看配置后的服务信息</h6><p>命令:<br>1) Reids客户端使用指定端口连接Redis服务器<br>./redis-cli -p 端口<br>2) 查看服务器信息<br>info replication</p><p>登录到Master: 6380</p><p><img src="/images/redis/redis147.png" alt="Redis"><br>查看当前服务信息<br>在客户端的Redis内执行命令 info replication<br>Master服务的查看结果:<br><img src="/images/redis/redis148.png" alt="Redis"></p><p>在新的Xshell窗口分别登录到6382,6384查看信息<br><img src="/images/redis/redis149.png" alt="Redis"><br>6384登录内容也同6382。</p><h6 id="向Master写入数据"><a href="#向Master写入数据" class="headerlink" title="向Master写入数据"></a>向Master写入数据</h6><p>在6380执行flushall清除数据,避免干扰的测试数据。生产环境避免使用。<br><img src="/images/redis/redis150.png" alt="Redis"></p><h6 id="在从Salve读数据"><a href="#在从Salve读数据" class="headerlink" title="在从Salve读数据"></a>在从Salve读数据</h6><p>6382,6384都可以读主Master的数据,不能写<br><img src="/images/redis/redis151.png" alt="Redis"></p><p>Salve写数据失败<br><img src="/images/redis/redis152.png" alt="Redis"></p><h5 id="容灾处理"><a href="#容灾处理" class="headerlink" title="容灾处理"></a>容灾处理</h5><p>当Master服务出现故障,需手动将slave中的一个提升为master,剩下的slave挂至新的master上(冷处理:机器挂掉了,再处理)<br>命令:<br>1) slaveof no one, 将一台slave服务器提升为Master(提升某slave为master)<br>2) slaveof 127.0.0.1 6381 (将slave挂至新的master上)</p><p>执行步骤:</p><h6 id="将Master-6380停止-模拟挂掉"><a href="#将Master-6380停止-模拟挂掉" class="headerlink" title="将Master:6380停止 (模拟挂掉)"></a>将Master:6380停止 (模拟挂掉)</h6><p><img src="/images/redis/redis153.png" alt="Redis"><br><img src="/images/redis/redis154.png" alt="Redis"></p><h6 id="选择一个Slave升到Master,其它的Slave挂到新提升的Master"><a href="#选择一个Slave升到Master,其它的Slave挂到新提升的Master" class="headerlink" title="选择一个Slave升到Master,其它的Slave挂到新提升的Master"></a>选择一个Slave升到Master,其它的Slave挂到新提升的Master</h6><p><img src="/images/redis/redis155.png" alt="Redis"></p><h6 id="将其它Slave挂到新的Master"><a href="#将其它Slave挂到新的Master" class="headerlink" title="将其它Slave挂到新的Master"></a>将其它Slave挂到新的Master</h6><p>在Slave 6384身上执行<br><img src="/images/redis/redis156.png" alt="Redis"><br>现在的主(Master/Slave)关系: Master是6382, Slave是6384<br>查看6382:<br><img src="/images/redis/redis157.png" alt="Redis"></p><h6 id="原来的服务器重新添加到主从结构中"><a href="#原来的服务器重新添加到主从结构中" class="headerlink" title="原来的服务器重新添加到主从结构中"></a>原来的服务器重新添加到主从结构中</h6><p>6380的服务器修改后,从新工作,需要把它添加到现有的Master/Slave中<br>先启动6380的Redis服务<br><img src="/images/redis/redis158.png" alt="Redis"><br>连接到6380端口<br><img src="/images/redis/redis159.png" alt="Redis"><br>当前服务挂到Master上<br><img src="/images/redis/redis160.png" alt="Redis"></p><h6 id="查看新的Master信息"><a href="#查看新的Master信息" class="headerlink" title="查看新的Master信息"></a>查看新的Master信息</h6><p>在6382执行:<br><img src="/images/redis/redis161.png" alt="Redis"><br>现在的Master/Slave关系是:<br>Master: 6382<br>Slave: 6380<br>Slave: 6384</p><h5 id="操作命令"><a href="#操作命令" class="headerlink" title="操作命令"></a>操作命令</h5><p>进入客户端需指定端口 ./redis-cli -p 6380<br>不配置启动默认都是主master<br>info replication 查看redis服务器所处角色</p><h5 id="总结-2"><a href="#总结-2" class="headerlink" title="总结"></a>总结</h5><p>1) 一个master可以有多个slave<br>2) salve下线,读请求的处理性能下降<br>3) master下线,写请求无法执行<br>4) 当master发生故障,需手动将其中一条slave使用slaveof no noe命令提示为master,其它slave执行slaveof命令指向这个新的master,从新的master处同步数据<br>5) 主从复制模式的故障转移需要手动操作,要实现自动化处理,这就需要Sentinel哨兵,实现故障自动转移。</p><h4 id="高可用Sentinel哨兵"><a href="#高可用Sentinel哨兵" class="headerlink" title="高可用Sentinel哨兵"></a>高可用Sentinel哨兵</h4><p>Snentinel哨兵是redis官方提供的高可用方案,可用用它来监控多个Redis服务实例的运行情况。Redis Sendtinel是一个运行在特使模式下的Redis服务器。Redis Sentinel是在多个Sentinel进程环境下相互协作工作的。</p><p>Sentinel系统有三个主要任务</p><ul><li>监控: Sentinel不断的检查主服务和从服务器是否按照预期正常工作。</li><li>提醒: 被监控的Redis出现问题时,Sentinel会通知管理员或其他应用程序。</li><li>自动故障转移: 监控的主Redis不能正常工作,Sentinel会开始进行故障迁移操作。将一个从服务器升级新的主服务器。让其他从服务器挂到新的主服务器。同时向客户端提供新的主服务器地址。<br><img src="/images/redis/redis162.png" alt="Redis"></li></ul><h5 id="Sentinel配置"><a href="#Sentinel配置" class="headerlink" title="Sentinel配置"></a>Sentinel配置</h5><p>Sentinel配置文件<br>复制三份Sentinel.conf文件:<br><img src="/images/redis/redis163.png" alt="Redis"></p><p>Sentinel系统默认port是26379。 三个配置port分别设置为26380, 26382, 26384。<br>三个文件分别命名为:</p><ul><li>sentinel26380.conf</li><li>sentinel26382.conf</li><li>sentinel26384.conf<br>执行复制命令 cp sentinel.conf xxx.conf<br><img src="/images/redis/redis164.png" alt="Redis"></li></ul><h5 id="三份sentinel配置文件修改"><a href="#三份sentinel配置文件修改" class="headerlink" title="三份sentinel配置文件修改:"></a>三份sentinel配置文件修改:</h5><p>1) 修改port 26380、 port 26382、 port 26384<br>2) 修改sentinel monitor mymaster 127.0.0.1 6380 2<br>格式: sentinel monitor &lt;name> &lt;masterIP> &lt;masterPort> &lt;Quorum投票数></p><p>Sentinel监控主(Master)Redis,Sentinel根据Master的配置自动发现Master的Slave,Sentinel默认端口号为26379。<br><img src="/images/redis/redis165.png" alt="Redis"><br>sentinel26380.conf<br>1) 修改port<br><img src="/images/redis/redis166.png" alt="Redis"><br>2) 修改监控的master地址<br><img src="/images/redis/redis167.png" alt="Redis"><br>sentinel26382.conf 修改port 26382, master的port 6382<br>sentinel26384.conf 修改port 26384, master的port 6382</p><h5 id="启动主从-Master-Slave-Redis"><a href="#启动主从-Master-Slave-Redis" class="headerlink" title="启动主从(Master/Slave) Redis"></a>启动主从(Master/Slave) Redis</h5><p>启动Redis<br><img src="/images/redis/redis168.png" alt="Redis"></p><p>查看Master的配置信息<br>连接到6382<br><img src="/images/redis/redis169.png" alt="Redis"><br>使用info命令查看Master/Slave<br><img src="/images/redis/redis170.png" alt="Redis"></p><h5 id="启动Sentinel"><a href="#启动Sentinel" class="headerlink" title="启动Sentinel"></a>启动Sentinel</h5><p>redis安装时make编译后就产生了redis-sentinel程序文件,可以在一个redis中运行多个sentinel进程。</p><p>启动一个运行在Sentinel模式下的Redis服务实例<br>./redis-sentinel sentinel配置文件</p><p>执行以下三条命令,将创建三个监视主服务器的Sentinel实例<br>./redis-sentinel ../sentinel26380.conf<br>./redis-sentinel ../sentinel26382.conf<br>./redis-sentinel ../sentinel26384.conf</p><p>在XShell开启三个窗口分别执行:<br><img src="/images/redis/redis171.png" alt="Redis"><br><img src="/images/redis/redis172.png" alt="Redis"><br><img src="/images/redis/redis173.png" alt="Redis"></p><h5 id="主Redis不能工作"><a href="#主Redis不能工作" class="headerlink" title="主Redis不能工作"></a>主Redis不能工作</h5><p>让Master的Redis停止服务,执行shutdown<br>先执行info replication确认Master的Redis,在执行shutdown<br><img src="/images/redis/redis174.png" alt="Redis"></p><p>查看当前Redis的进程情况<br><img src="/images/redis/redis175.png" alt="Redis"></p><h5 id="Sentinel起的作用"><a href="#Sentinel起的作用" class="headerlink" title="Sentinel起的作用"></a>Sentinel起的作用</h5><p>在Master执行shutdown后,稍微等一会Sentinel要进行投票计算,从可用的Slave选举新的Master。<br>查看Sentinel日志,三个Sentinel窗口的日志是一样的。<br><img src="/images/redis/redis176.png" alt="Redis"></p><p>查看新的Master<br><img src="/images/redis/redis177.png" alt="Redis"></p><p>查看原Slave的变化<br><img src="/images/redis/redis178.png" alt="Redis"></p><h5 id="新的Redis加入Sentinel系统,自动加入Master"><a href="#新的Redis加入Sentinel系统,自动加入Master" class="headerlink" title="新的Redis加入Sentinel系统,自动加入Master"></a>新的Redis加入Sentinel系统,自动加入Master</h5><p>重新启动6382<br><img src="/images/redis/redis179.png" alt="Redis"><br>查看6384的信息<br><img src="/images/redis/redis180.png" alt="Redis"><br>测试数据:在Master写入数据<br><img src="/images/redis/redis181.png" alt="Redis"><br>在6382写入数据,不能写入<br><img src="/images/redis/redis182.png" alt="Redis"></p><h5 id="监控"><a href="#监控" class="headerlink" title="监控"></a>监控</h5><p>1) Sentinel会不断检查Master和Slave是否正常。<br>2) 如果Sentinel挂了,就无法监控,所以需要多个哨兵,组成Sentinel网络,一个健康的Sentinel至少有3个应用。彼此在独立的物理机器或虚拟机。<br>3) 监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监控服务器的信息。<br>4) 当一个Sentinel认为被监控的服务器已经下线时,它会向网络中的其它Sentinel进行确认,判断该服务器是否真的已经下线。<br>5) 如果下线的服务器为主服务器,那么Sentinel网络将对下线主服务器进行自动故障转移,通过将下线的主服务的某个服务器提升为新的主服务器,并让其从服务器转移到新的主服务器下,以此来让系统重新回到正常状态。<br>6) 下线的旧主服务器重新上线,Sentinel会让它成为从,挂到新的主服务器下。</p><h5 id="总结-3"><a href="#总结-3" class="headerlink" title="总结"></a>总结</h5><p>主从复制,解决了读请求的负担,从节点下线,会使得读请求能力有所下降,Master下线,写请求无法执行。<br>Sentinel会在Master下线后自动执行故障转移操作,提升一台Slave为Master,并让其它Slave成为新的Master的Slave。</p><h3 id="安全设置"><a href="#安全设置" class="headerlink" title="安全设置"></a>安全设置</h3><h4 id="设置密码"><a href="#设置密码" class="headerlink" title="设置密码"></a>设置密码</h4><p>访问Redis默认是没有密码的,这样不安全,任意用户都可以访问。可以启动使用密码才能访问Redis。设置Redis的访问密码,修改redis.conf中这行requirepass密码。密码要比较复杂,不容易破解,而且需要定期修改。因为redis速度相当快,所以在一台比较好的服务器下,一个外部用户可以再一秒钟进行150K次的密码尝试,需要指定非常非常强的密码来防止暴力破解。</p><h5 id="开启访问密码设置"><a href="#开启访问密码设置" class="headerlink" title="开启访问密码设置"></a>开启访问密码设置</h5><p>修改redis.conf,使用vim命令。找到requirepass行去掉注释,requirepass空格后就是密码。<br>例1: 设置访问密码是123456,这是练习使用,生产环境要设置复杂的密码<br>修改redis.conf,文件480行左右。原始内容:<br><img src="/images/redis/redis183.png" alt="Redis"><br>修改后:<br><img src="/images/redis/redis184.png" alt="Redis"><br>查看修改结果:<br><img src="/images/redis/redis185.png" alt="Redis"></p><h5 id="访问有密码的Redis"><a href="#访问有密码的Redis" class="headerlink" title="访问有密码的Redis"></a>访问有密码的Redis</h5><p>如果Redis已经启动,关闭后重新启动。</p><p>访问有密码的Redis两种方式:<br>1) 在连接到客户端后,使用命令auth 密码,命令执行成功后,可以正常使用Redis<br>2) 在连接客户端时使用-a密码。例如./redis-cli -h ip -p port -a password</p><p>启动Redis<br><img src="/images/redis/redis186.png" alt="Redis"><br>使用1)访问<br><img src="/images/redis/redis187.png" alt="Redis"><br>输入命令auth密码<br><img src="/images/redis/redis188.png" alt="Redis"></p><p>使用2)方式<br><img src="/images/redis/redis189.png" alt="Redis"></p><h4 id="绑定ip"><a href="#绑定ip" class="headerlink" title="绑定ip"></a>绑定ip</h4><p>修改redis.conf文件,把# bind 127.0.0.1前面的注释#去掉,然后把127.0.0.1改成允许访问你redis服务器的ip地址,表示只允许该ip进行访问。多个ip使用空格分割。<br>例如 bind 192.168.1.100 192.168.1.10</p><h4 id="修改默认端口"><a href="#修改默认端口" class="headerlink" title="修改默认端口"></a>修改默认端口</h4><p>修改redis的端口,这一点很重要,使用默认的端口很危险,redis.conf中修改port 6379将其修改为自己指定的端口(可随意),端口1024是保留给操作系统使用的。用户可以使用的范围是1024-65535<br><img src="/images/redis/redis190.png" alt="Redis"></p><p>使用 -p 参数指定端口,例如: ./redis-cli -p 新设置端口</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h3 id=&quot;Redis事物&quot;&gt;&lt;a href=&quot;#Redis事物&quot; class=&quot;headerlink&quot; title=&quot;Redis事物&quot;&gt;&lt;/a&gt;
</summary>
<category term="数据库" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Redis" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/"/>
<category term="Redis" scheme="http://smartdot.club/tags/Redis/"/>
</entry>
<entry>
<title>第1章 Nginx介绍</title>
<link href="http://smartdot.club/Nginx/%E7%AC%AC1%E7%AB%A0%20Nginx%E4%BB%8B%E7%BB%8D/"/>
<id>http://smartdot.club/Nginx/第1章 Nginx介绍/</id>
<published>2019-03-01T14:17:09.000Z</published>
<updated>2019-03-12T01:31:25.689Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Nginx介绍"><a href="#Nginx介绍" class="headerlink" title="Nginx介绍"></a>Nginx介绍</h2><p>Nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。<br>最早由俄罗斯的程序设计师Igor SYsoev所开发,并在一个BSD-like协议下发行。<br>其特点是轻量级,占有内存少,并发能力强,目前发展势头强劲。<br>web领域最经典的lamp组合已经变成lnmp组合。</p><p>注:开源协议:GPL(带有病毒性质,使用GPL必须以GPL开源)、BSD(可以商用,相对宽松)、apache。</p><h3 id="谁在用Nginx"><a href="#谁在用Nginx" class="headerlink" title="谁在用Nginx"></a>谁在用Nginx</h3><p>目前国内的一线门户网站,如网易、搜狐、腾讯。以及大量新兴网站,如自学it网、豆瓣。</p><h3 id="Nginx的占有率变化"><a href="#Nginx的占有率变化" class="headerlink" title="Nginx的占有率变化"></a>Nginx的占有率变化</h3><p>下图是世界范围内,排名前1000,10000的网站的webserver比例<br><img src="/images/nginx/01.png" alt="Nginx"></p><p>Apache占有率高主要是历史原因。因为网站一旦运行,不轻易更换。</p><h2 id="Nginx编译与启动"><a href="#Nginx编译与启动" class="headerlink" title="Nginx编译与启动"></a>Nginx编译与启动</h2><h3 id="编译安装"><a href="#编译安装" class="headerlink" title="编译安装"></a>编译安装</h3><p>到官方网站:<a href="http:/nginx.org" title="nginx" target="_blank" rel="noopener">http:/nginx.org</a>寻找最新stable版下载。例如当前最新的<a href="http://nginx.org/download/nginx-1.15.9.tar.gz" title="nginx" target="_blank" rel="noopener">http://nginx.org/download/nginx-1.15.9.tar.gz</a><br>安装准备:nginx依赖于pcre库,要先安装pcre<br></p><figure class="highlight vala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># yum install pcre pcre-devel</span></span><br><span class="line"><span class="meta"># cd /usr/local/src</span></span><br><span class="line"><span class="meta"># wget http://nginx.org/download/nginx-1.15.9.tar.gz</span></span><br><span class="line"><span class="meta"># tar -zxvf nginx-1.15.9.tar.gz</span></span><br><span class="line"><span class="meta"># cd nginx-1.15.9</span></span><br><span class="line"><span class="meta"># ./configure --prefix=/usr/local/nginx</span></span><br><span class="line"><span class="meta"># make &amp;&amp; make install</span></span><br></pre></td></tr></table></figure><p></p><p>为什么要先装pcre?<br>因为:nginx要在rewrite是要解析正则表达式,PCRE是正则解析库。</p><h3 id="nginx目录介绍"><a href="#nginx目录介绍" class="headerlink" title="nginx目录介绍"></a>nginx目录介绍</h3><p>cd /usr/local/nginx,看到如下4个目录</p><ul><li>conf: 配置文件</li><li>html: 网页文件</li><li>logs: 日志文件</li><li>sbin: 主要二进制程序</li></ul><h3 id="启动nginx"><a href="#启动nginx" class="headerlink" title="启动nginx"></a>启动nginx</h3><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">cd</span> <span class="string">/usr/local/nginx</span></span><br><span class="line"><span class="string">./sbin/nginx</span></span><br></pre></td></tr></table></figure><p>如果没有出现错误提示,则启动成功了。如果有错误提示,则根据错误提示再做处理,常见的错误是“80端口被占用”。</p><h3 id="80端口被占用的解决方案"><a href="#80端口被占用的解决方案" class="headerlink" title="80端口被占用的解决方案"></a>80端口被占用的解决方案</h3><p>如果出现不能绑定80端口,80端口已经被占用。<br><img src="/images/nginx/02.png" alt="Nginx"><br>(有时候是自己安装了apache,nginx等,还有更多情况是操作系统自带了apche并作为服务启动)<br><img src="/images/nginx/03.png" alt="Nginx"><br>解决:把占用80端口的软件或服务关闭即可。<br>如果是linux系统自带的apache且自动启动。service httpd stop<br>如果是自行编译安装的,可以# /path/to/apacht/bin/apachctl stop</p><p>如果检测确实没有其他程序占据80端口,但仍报此错,则问题可能是因为Nignx试图同时监听IPV4和IPV6的80端口导致的的(Nginx 1.4.0版本曾有此问题)<br></p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">server</span> &#123;</span><br><span class="line"><span class="attribute"><span class="nomarkup">listen</span></span>: 80</span><br><span class="line"><span class="attribute"><span class="nomarkup">listen</span></span><span class="meta"> [::]:80;</span></span><br><span class="line"><span class="meta">&#125;</span></span><br></pre></td></tr></table></figure><p></p><p>可以按如下2种办法修改<br></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line"><span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"><span class="attribute">listen</span> [::]:<span class="number">80</span> ipv6pnly=<span class="literal">on</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>或者<br></p><figure class="highlight less"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">server</span> &#123;</span><br><span class="line"><span class="selector-tag">listen</span> <span class="selector-attr">[::]</span><span class="selector-pseudo">:80</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h2 id="Nginx-命令参数"><a href="#Nginx-命令参数" class="headerlink" title="Nginx 命令参数"></a>Nginx 命令参数</h2><p>kill -INT 17800<br>kill -USR1<br>如果不愿意用信号来控制,nginx程序也可以用一些参数,达到效果。如:<br>nginx -t 作用:测试配置是否正确<br>nginx -s reload 作用:加载最新配置<br>nginx -s stop 作用:立即停止(停止请求立即停止)<br>nginx -s quit 作用:优雅停止(请求结束然后停止)<br>nginx -s reopen 作用:重新打开日志</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Nginx介绍&quot;&gt;&lt;a href=&quot;#Nginx介绍&quot; class=&quot;headerlink&quot; title=&quot;Nginx介绍&quot;&gt;&lt;/a&gt;
</summary>
<category term="Nginx" scheme="http://smartdot.club/categories/Nginx/"/>
<category term="Nginx" scheme="http://smartdot.club/tags/Nginx/"/>
</entry>
<entry>
<title>第3章 Redis数据类型操作命令</title>
<link href="http://smartdot.club/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E7%AC%AC3%E7%AB%A0%20Redis%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4/"/>
<id>http://smartdot.club/数据库/Redis/第3章 Redis数据类型操作命令/</id>
<published>2019-03-01T12:17:09.000Z</published>
<updated>2019-03-07T08:42:46.394Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="Redis数据类型操作命令"><a href="#Redis数据类型操作命令" class="headerlink" title="Redis数据类型操作命令"></a>Redis数据类型操作命令</h2><h3 id="字符串类型-string"><a href="#字符串类型-string" class="headerlink" title="字符串类型 (string)"></a>字符串类型 (string)</h3><p>字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据,序列化后的数据,JSON化的对象,甚至是一张图片。</p><h4 id="基本命令"><a href="#基本命令" class="headerlink" title="基本命令"></a>基本命令</h4><p>先测试能连接到redis服务器<br><img src="/images/redis/redis21.png" alt="Redis"></p><h5 id="set"><a href="#set" class="headerlink" title="set"></a>set</h5><p>将字符串值value设置到key中<br>语法:set key value<br><img src="/images/redis/redis42.png" alt="Redis"><br>查看已经插入的key<br><img src="/images/redis/redis43.png" alt="Redis"><br>向已经存在的key设置新的value,会覆盖原来的值</p><h5 id="get"><a href="#get" class="headerlink" title="get"></a>get</h5><p>获取key中设置的字符串值<br>语法:get key<br>例如:获取username这个key对应的value<br><img src="/images/redis/redis44.png" alt="Redis"></p><h5 id="incr"><a href="#incr" class="headerlink" title="incr"></a>incr</h5><p>将key中存储的数字值加1,如果key不存在,则key的值先被初始化为0再执行incr操作(只能对数字类型的数据操作)<br>语法: incr key<br>例1:操作key值增加1<br><img src="/images/redis/redis45.png" alt="Redis"><br>例2:对非数字的值操作是不行的<br><img src="/images/redis/redis46.png" alt="Redis"></p><h5 id="decr"><a href="#decr" class="headerlink" title="decr"></a>decr</h5><p>将key中存储的数字值减1,如果key不存在,那么key的值先被初始化为0再执行decr操作(只能对数字类型的数据操作)<br>语法: decr key<br>例1: 不存在的key,初始值为0,在减1。<br><img src="/images/redis/redis47.png" alt="Redis"><br>例2:对存在的数字值得key,减1。<br>先执行incr index,增加到3<br><img src="/images/redis/redis48.png" alt="Redis"><br>incr,decr在实现关注人数上,文章的点击数上。</p><h5 id="append"><a href="#append" class="headerlink" title="append"></a>append</h5><p>语法: append key value<br>说明: 如果key存在,则将value追加到key原来旧值得末尾<br>如果key不存在,则将key设置值为value<br>返回值: 追加字符串之后的总长度<br>例1:追加内容到存在的key<br><img src="/images/redis/redis49.png" alt="Redis"><br>例2:追加到不存在的key,同set key value<br><img src="/images/redis/redis50.png" alt="Redis"></p><h4 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h4><h5 id="strlen"><a href="#strlen" class="headerlink" title="strlen"></a>strlen</h5><p>语法: strlen key<br>说明: 返回key所存储的字符串值的长度<br>返回值:<br>1) 如果key存在,返回字符串值的长度<br>2)如果key不存在,返回0</p><p>例1:计算存在key的字符串长度<br>设置中文set k4中文长度,按字符个数计算<br><img src="/images/redis/redis51.png" alt="Redis"><br>例2:计算不存在的key<br><img src="/images/redis/redis52.png" alt="Redis"></p><h5 id="getrange"><a href="#getrange" class="headerlink" title="getrange"></a>getrange</h5><p>语法:getrange key start end<br>作用:获取key中字符串值从start开始到end结束的字符串,包括start和end,负数表示从字符串的末尾开始,-1表示最后一个字符。<br>返回值:截取的字符串<br>使用的字符串 key:school, value:bjpowernode<br>例1:截取从2到5的字符串<br><img src="/images/redis/redis53.png" alt="Redis"><br>例2:从字符串尾部截取,start,end是负数,最后一位是-1<br><img src="/images/redis/redis54.png" alt="Redis"><br>例3:超出字符串范围的截取,获取合理的字符串。<br><img src="/images/redis/redis55.png" alt="Redis"></p><h5 id="setrange"><a href="#setrange" class="headerlink" title="setrange"></a>setrange</h5><p>语法: setrange key offset value<br>说明: 用value覆盖(替换)key的存储的值从offset开始,不存在的key做空白字符串。<br>返回值: 修改后的字符串的长度。<br>例1:替换给定的字符串<br><img src="/images/redis/redis56.png" alt="Redis"><br>例2:设置不存在的key<br><img src="/images/redis/redis57.png" alt="Redis"></p><h5 id="mset"><a href="#mset" class="headerlink" title="mset"></a>mset</h5><p>语法: mset key value[key value···]<br>说明: 同时设置一个或多个key-value对<br>返回值: OK<br>例1:一次设置多个key, value<br><img src="/images/redis/redis58.png" alt="Redis"></p><h5 id="mget"><a href="#mget" class="headerlink" title="mget"></a>mget</h5><p>语法: mget key[key ···]<br>作用: 获取所有(一个或多个)给定key的值<br>返回值: 包含所有key的列表</p><p>例1:返回多个key的存储值<br><img src="/images/redis/redis58.png" alt="Redis"><br>例2:返回不存在的key<br><img src="/images/redis/redis60.png" alt="Redis"></p><h3 id="哈希类型-hash"><a href="#哈希类型-hash" class="headerlink" title="哈希类型 hash"></a>哈希类型 hash</h3><p>redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。</p><h4 id="基本命令-1"><a href="#基本命令-1" class="headerlink" title="基本命令"></a>基本命令</h4><h5 id="hset"><a href="#hset" class="headerlink" title="hset"></a>hset</h5><p>语法:hset hash表的key feld value<br>作用:将哈希表key中的域field的值设为vlaue,如果key不存在,则新建hash表,执行赋值,如果有field,则覆盖值。<br>返回值:<br>1) 如果field是hash表中新field,且设置值成功,返回1<br>2)如果field已经存在,旧值覆盖新值,返回0</p><p>例1:新的field<br><img src="/images/redis/redis61.png" alt="Redis"><br>例2:覆盖旧的field<br><img src="/images/redis/redis62.png" alt="Redis"></p><h5 id="hget"><a href="#hget" class="headerlink" title="hget"></a>hget</h5><p>语法: hget key field<br>作用: 获取哈希表key中给定域field的值<br>返回值: field域的值,如果key不存在或者field不存在返回nil<br>例1:获取存在key值得某个域的值<br><img src="/images/redis/redis63.png" alt="Redis"><br>例2:获取不存在的field<br><img src="/images/redis/redis64.png" alt="Redis"></p><h5 id="hmset"><a href="#hmset" class="headerlink" title="hmset"></a>hmset</h5><p>语法: hmset key field value [field value···]<br>说明: 同时将多个field-value(域-值)设置到哈希表key中,此命令会覆盖已经存在的field,hash表key不存在,创建空的hash表,执行hmset。<br>返回值:设置成功返回OK,如果失败返回一个错误。<br>例1:同时设置多个field-value<br><img src="/images/redis/redis65.png" alt="Redis"><br>使用redis-desktop-manager工具查看hash表,website的数据结构<br><img src="/images/redis/redis66.png" alt="Redis"><br>例2:key类型不是hash,产生错误。<br><img src="/images/redis/redis67.png" alt="Redis"></p><h5 id="hmget"><a href="#hmget" class="headerlink" title="hmget"></a>hmget</h5><p>语法: mhget key field[field ···]<br>作用: 获取哈希表key中一个或多个给定域的值<br>返回值: 返回和field顺序对应的值,如果field不存在,返回nil<br>例1:获取多个field的值<br><img src="/images/redis/redis68.png" alt="Redis"></p><h5 id="hgetall"><a href="#hgetall" class="headerlink" title="hgetall"></a>hgetall</h5><p>语法: hgetall key<br>作用: 获取哈希表key中所有的域和值<br>返回值:以列表形式返回hash中域和域的值,key不存在,返回空hash<br>例1:返回key对应的所有域和值<br><img src="/images/redis/redis69.png" alt="Redis"><br>例2:不存在的key,返回空列表<br><img src="/images/redis/redis70.png" alt="Redis"></p><h5 id="hdel"><a href="#hdel" class="headerlink" title="hdel"></a>hdel</h5><p>语法: hdel key field[field ···]<br>作用: 删除哈希表key中的一个或多个指定域field,不存在field直接忽略<br>返回值:成功删除的field的数量<br>例1:删除指定field<br><img src="/images/redis/redis71.png" alt="Redis"></p><h4 id="常用命令-1"><a href="#常用命令-1" class="headerlink" title="常用命令"></a>常用命令</h4><h5 id="hkeys"><a href="#hkeys" class="headerlink" title="hkeys"></a>hkeys</h5><p>语法: hkeys key<br>作用: 查看哈希表key中的所有field域<br>返回值: 包含所有field的列表,key不存在返回空列表<br>例1:查看website所有的域名称:<br><img src="/images/redis/redis72.png" alt="Redis"></p><h5 id="hvals"><a href="#hvals" class="headerlink" title="hvals"></a>hvals</h5><p>语法: hvals key<br>作用: 返回哈希表中所有域的值<br>返回值: 包含哈希表所有域值的列表,key不存在返回空列表。<br>例1:显示website哈希表所有域的值<br><img src="/images/redis/redis73.png" alt="Redis"></p><h5 id="hexists"><a href="#hexists" class="headerlink" title="hexists"></a>hexists</h5><p>语法: hexists key field<br>作用: 查看哈希表key中,给定域field是否存在<br>返回值: 如果field存在,返回1,其他返回0<br>例1:查看存在key中的field域是否存在<br><img src="/images/redis/redis74.png" alt="Redis"></p><h3 id="列表-list"><a href="#列表-list" class="headerlink" title="列表 list"></a>列表 list</h3><p>Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)</p><h4 id="基本命令-2"><a href="#基本命令-2" class="headerlink" title="基本命令"></a>基本命令</h4><h5 id="lpush"><a href="#lpush" class="headerlink" title="lpush"></a>lpush</h5><p>语法: lpush key value [value ···]<br>作用: 将一个或多个值value插入到列表key的表头(最左边),从左边开始加入值,从左到右的顺序依次插入到表头<br>返回值: 数字,新列表的长度<br>例1:将a,b,c插入到mylist列表类型<br><img src="/images/redis/redis75.png" alt="Redis"><br>在redis-desktop-manager显示<br><img src="/images/redis/redis76.png" alt="Redis"><br>插入图示:<br><img src="/images/redis/redis77.png" alt="Redis"><br>例2:插入重复值到list列表类型<br><img src="/images/redis/redis78.png" alt="Redis"><br>在redis-desktop-manager显示<br><img src="/images/redis/redis79.png" alt="Redis"></p><h5 id="rpush"><a href="#rpush" class="headerlink" title="rpush"></a>rpush</h5><p>语法: rpush key value [value···]<br>作用: 将一个或多个值value插入到列表key的表尾(最右边),各个value值按从左到右的顺序依次插入到表尾。<br>返回值: 数字,新列表的长度<br>例1: 插入多个值到列表<br><img src="/images/redis/redis80.png" alt="Redis"><br>在redis-desktop-manager显示<br><img src="/images/redis/redis81.png" alt="Redis"></p><h5 id="lrange"><a href="#lrange" class="headerlink" title="lrange"></a>lrange</h5><p>语法:lrange key start stop<br>作用:获取列表key中指定区间内的元素,0表示列表的第一个元素,以1表示列表的第二个元素;start,stop是列表的下标值,也可以负数的下标,-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。start,stop超出列表的范围不会出现错误。<br>例1:返回列表的全部内容<br><img src="/images/redis/redis82.png" alt="Redis"></p><h5 id="lindex"><a href="#lindex" class="headerlink" title="lindex"></a>lindex</h5><p>语法: lindex key index<br>作用: 获取列表key中下标为指定index的元素,列表元素不删除,只是查询。0表示列表的第一个元素,以1表示列表的第二个元素;start,stop是列表的下标值,也可以负数为下标,-1表示类别的最后一个元素,-2表列表的倒数第二个元素,一次类推。<br>返回值: 指定下标的元素;index不在列表范围,返回nil<br>例1:返回下标是1的元素<br><img src="/images/redis/redis83.png" alt="Redis"><br>例2:不存在的下标<br><img src="/images/redis/redis84.png" alt="Redis"></p><h5 id="llen"><a href="#llen" class="headerlink" title="llen"></a>llen</h5><p>语法: llen key<br>作用: 获取列表key的长度<br>返回值: 数值,列表的长度;key不存在返回0<br>例1:显示存在key的列表元素的个数<br><img src="/images/redis/redis85.png" alt="Redis"></p><h4 id="常用命令-2"><a href="#常用命令-2" class="headerlink" title="常用命令"></a>常用命令</h4><h5 id="lrem"><a href="#lrem" class="headerlink" title="lrem"></a>lrem</h5><p>语法: lrem key count value<br>作用: 根据参数count的值,溢出列表中与参数value相等的元素,count&gt;0,从列表的左侧向右开始移除;count&lt;0从列表的尾部开始移除;count=0移除表中所有与value相等的值。<br>返回值: 数值,移除的元素个数<br>例1:删除2个相同的列表元素<br><img src="/images/redis/redis86.png" alt="Redis"><br>例2:删除列表中所有的指定元素,删除所有的java<br><img src="/images/redis/redis87.png" alt="Redis"></p><h5 id="lset"><a href="#lset" class="headerlink" title="lset"></a>lset</h5><p>语法: lset key index value<br>作用: 将列表key下标为index的元素的值设置为value。<br>返回值: 设置成功返回OK;key不存在或者index超出范围返回错误信息。<br>例1:设置下标2的value为”c”<br><img src="/images/redis/redis88.png" alt="Redis"></p><h5 id="linsert"><a href="#linsert" class="headerlink" title="linsert"></a>linsert</h5><p>语法: linsert key BEFORE|ALFTER pivot value<br>作用: 将值value插入到列表key当中位于值pivot之前或之后的位置。key不存在,pivot不在列表中,不执行任何操作。<br>返回值: 命令执行成功,返回新列表的长度,没有找到pivot返回-1,key不存在返回0。<br>例1:修改列表arch,在值dao之前加入service<br><img src="/images/redis/redis89.png" alt="Redis"><br>例2:操作不存在的pivot<br><img src="/images/redis/redis90.png" alt="Redis"></p><h3 id="集合类型-set"><a href="#集合类型-set" class="headerlink" title="集合类型 set"></a>集合类型 set</h3><p>Redis的Set是string类型的无序集合,集合成员是唯一的,即集合中不能出现重复的数据</p><h4 id="基本命令-3"><a href="#基本命令-3" class="headerlink" title="基本命令"></a>基本命令</h4><h5 id="sadd"><a href="#sadd" class="headerlink" title="sadd"></a>sadd</h5><p>语法: sadd key member [member···]<br>作用: 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略,不会再加入。<br>返回值: 加入到集合的新元素的个数。不包括被忽略的元素。<br>例1:添加单个元素<br><img src="/images/redis/redis91.png" alt="Redis"><br>例2:添加多个元素<br><img src="/images/redis/redis92.png" alt="Redis"></p><h5 id="smembers"><a href="#smembers" class="headerlink" title="smembers"></a>smembers</h5><p>语法: smembers key<br>作用: 获取集合key中的所有成员元素,不存在的ky视为空集合<br>例1: 查看集合的所有元素<br><img src="/images/redis/redis93.png" alt="Redis"><br>例2: 查看不存在的集合<br><img src="/images/redis/redis94.png" alt="Redis"></p><h5 id="sismember"><a href="#sismember" class="headerlink" title="sismember"></a>sismember</h5><p>语法: sismember key member<br>作用: 判断member元素是否是集合key的成员<br>返回值: member是集合成员返回1,其他返回0。<br>例1: 检查元素是否存在集合中<br><img src="/images/redis/redis95.png" alt="Redis"></p><h5 id="scard"><a href="#scard" class="headerlink" title="scard"></a>scard</h5><p>语法: scard key<br>作用: 获取集合里面的元素的个数<br>返回值: 数字,key的元素个数。其他情况返回0。<br>例1: 统计集合的大小<br><img src="/images/redis/redis96.png" alt="Redis"><br>例2: 统计不存在的key<br><img src="/images/redis/redis97.png" alt="Redis"></p><h5 id="srem"><a href="#srem" class="headerlink" title="srem"></a>srem</h5><p>语法: srem key member [member···]<br>作用: 删除集合key中的一个或多个member元素,不存在的元素被忽略。<br>返回值: 数字,成功删除的元素个数,不包括被忽略的元素。<br>例1:删除存在的一个元素,返回数字1<br><img src="/images/redis/redis98.png" alt="Redis"><br>例2:删除不存在的元素<br><img src="/images/redis/redis99.png" alt="Redis"></p><h4 id="常用命令-3"><a href="#常用命令-3" class="headerlink" title="常用命令"></a>常用命令</h4><h5 id="srandmember"><a href="#srandmember" class="headerlink" title="srandmember"></a>srandmember</h5><p>语法: srandmember key[count]<br>作用: 只提供key,随机返回集合中一个元素,元素不删除,依然在集合中;提供了count时,count是正数,返回包含count个数元素的集合,集合元素各不相同。count是负数,返回一个count绝对值的长度的集合,集合中元素可能会重复多次。<br>返回值: 一个元素;多个元素的集合。<br>例1: 随机显示集合的一个元素<br><img src="/images/redis/redis100.png" alt="Redis"><br>例2: 使用count参数,count是正数<br><img src="/images/redis/redis101.png" alt="Redis"><br>例3: 使用count参数,count是负数<br><img src="/images/redis/redis102.png" alt="Redis"></p><h5 id="spop"><a href="#spop" class="headerlink" title="spop"></a>spop</h5><p>语法: spop key [count]<br>作用: 随机从集合中删除一个元素,count是删除的元素个数。<br>返回值: 被删除的元素,key不存在或空集合返回nil<br>例1: 随机从集合删除一个元素<br><img src="/images/redis/redis103.png" alt="Redis"><br>例2: 随机删除指定个数的元素<br><img src="/images/redis/redis104.png" alt="Redis"></p><h3 id="有序集合类型-zset-sorted-set"><a href="#有序集合类型-zset-sorted-set" class="headerlink" title="有序集合类型 zset (sorted set)"></a>有序集合类型 zset (sorted set)</h3><p>Redis有序集合zset和集合set一样也是string类型元素的集合,且不允许重复的成员。不同的是zset的每个元素都会关联一个分数(分数可以重复),redis通过分数来为集合中的成员进行从小到大的排序。</p><h4 id="基本命令-4"><a href="#基本命令-4" class="headerlink" title="基本命令"></a>基本命令</h4><h5 id="zadd"><a href="#zadd" class="headerlink" title="zadd"></a>zadd</h5><p>语法: zadd key score member [score member···]<br>作用: 将一个或多个member元素及其score值加入到有序集合key中,如果member存在集合中,则更新值;score可以是整数或浮点数。<br>返回值: 数字,新添加的元素个数<br>例1: 创建保存学生成绩的集合<br><img src="/images/redis/redis105.png" alt="Redis"><br>例2: 使用浮点数作为scroe<br><img src="/images/redis/redis106.png" alt="Redis"></p><h5 id="zrange"><a href="#zrange" class="headerlink" title="zrange"></a>zrange</h5><p>语法: zrange key start stop [WITHSCORES]<br>作用: 查询有序集合,指定区间的内的元素。集合成员按score值从小到大来排序。start,stop都是从0开始。0是第一个元素,1是第二个元素,一次类推。以-1表示最后一个成员,-2表示倒数第二个成员。WITHSCORES选项让score和value一同返回。<br>返回值: 自定区间的成员集合<br>例1: 显示集合的全部元素,不显示score,不使用WITHSCORES<br><img src="/images/redis/redis107.png" alt="Redis"><br>例2: 显示集合全部元素,并使用WITHSCORES<br><img src="/images/redis/redis108.png" alt="Redis"><br>例3: 显示第0,1二个成员<br><img src="/images/redis/redis109.png" alt="Redis"><br>例4: 排序显示浮点数的score<br><img src="/images/redis/redis110.png" alt="Redis"></p><h5 id="zrevrange"><a href="#zrevrange" class="headerlink" title="zrevrange"></a>zrevrange</h5><p>语法: zrevrange key start stop [WITHSCORES]<br>作用: 返回有序集key中,指定区间内的成员。其中成员的位置按score值递减(从大到小)来排列。其它同zrange命令。<br>返回值: 自定区间的成员集合。<br>例1: 成绩榜<br><img src="/images/redis/redis111.png" alt="Redis"></p><h5 id="zrem"><a href="#zrem" class="headerlink" title="zrem"></a>zrem</h5><p>语法: zrem key member [member···]<br>作用: 删除有序集合key中的一个或多个成员,不存在的成员被忽略<br>返回值: 被成功删除的成员数量,不包括被忽略的成员。<br>例1: 删除指定一个成员wangwu<br><img src="/images/redis/redis112.png" alt="Redis"></p><h5 id="zcard"><a href="#zcard" class="headerlink" title="zcard"></a>zcard</h5><p>语法: zcard key<br>作用: 获取有序集key的元素成员的个数<br>返回值: key存在返回集合元素的个数,key不存在,返回0。<br>例1: 查询集合的元素个数<br><img src="/images/redis/redis113.png" alt="Redis"></p><h4 id="常用命令-4"><a href="#常用命令-4" class="headerlink" title="常用命令"></a>常用命令</h4><h5 id="zrangebyscore"><a href="#zrangebyscore" class="headerlink" title="zrangebyscore"></a>zrangebyscore</h5><p>语法: zrangebyscore key min max [WITHSCORES] [LIMIT offset count]<br>作用: 获取有序集key中,所有score值介于min和max之间(包括min和max)的成员,有序成员是按递增(从小到大)排序。min,max是包括在内,使用符合(表示不包括。min, max可以使用-inf, +inf表示最小和最大。 limit用来限制返回结果的数量和区间。 withsocres显示score和value。<br>返回值: 指定区间的集合数据。<br>使用的准备数据<br><img src="/images/redis/redis114.png" alt="Redis"><br>例1: 显示指定具体区间的数据<br><img src="/images/redis/redis115.png" alt="Redis"><br>例2: 显示指定具体区间的集合数据,开区间(不包括min,max)<br><img src="/images/redis/redis116.png" alt="Redis"><br>例3: 显示整个集合的所有数据<br><img src="/images/redis/redis117.png" alt="Redis"><br>例4: 使用limit<br>增加新的数据:<br><img src="/images/redis/redis118.png" alt="Redis"></p><p><img src="/images/redis/redis119.png" alt="Redis"><br>显示从第一个位置开始,取第一个元素。<br><img src="/images/redis/redis120.png" alt="Redis"></p><h5 id="zrevrangebyscore"><a href="#zrevrangebyscore" class="headerlink" title="zrevrangebyscore"></a>zrevrangebyscore</h5><p>语法: zrevrangebyscore key max min[WITHSCORES] [LIMIT offset count]<br>作用: 返回有序集key中,score值介于max和min之间(默认包括等于max或min)的所有的成员。有序集成员按score值递减(从大到小的次序排列)。其他同zrangebyscore<br>例1: 查询工资最高到3000之间的员工<br><img src="/images/redis/redis121.png" alt="Redis"></p><h5 id="zcount"><a href="#zcount" class="headerlink" title="zcount"></a>zcount</h5><p>语法: zcount key min max<br>作用: 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员的数量<br>例1: 求工资在3000-5000的员工数量<br><img src="/images/redis/redis122.png" alt="Redis"></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Redis数据类型操作命令&quot;&gt;&lt;a href=&quot;#Redis数据类型操作命令&quot; class=&quot;headerlink&quot; title=&quot;R
</summary>
<category term="数据库" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Redis" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/"/>
<category term="Redis" scheme="http://smartdot.club/tags/Redis/"/>
</entry>
<entry>
<title>第2章 Redis安装和使用</title>
<link href="http://smartdot.club/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E7%AC%AC2%E7%AB%A0%20Redis%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8/"/>
<id>http://smartdot.club/数据库/Redis/第2章 Redis安装和使用/</id>
<published>2019-02-28T12:17:09.000Z</published>
<updated>2019-03-06T14:51:58.362Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="Redis安装和使用"><a href="#Redis安装和使用" class="headerlink" title="Redis安装和使用"></a>Redis安装和使用</h2><p>Redis是当今非常流行的基于KV结构的作为Cache使用的NoSQL数据库</p><h3 id="Redis介绍"><a href="#Redis介绍" class="headerlink" title="Redis介绍"></a>Redis介绍</h3><p>Remote Dictionary Server(Redis)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的Key——Value数据库。Key字符串类型,其值(value)可以是字符串(String),哈希(Map),列表(list),集合(Sets)和有序集合(sorted sets)等类型,每种数据类型有自己专属命令。所以它通常也被称为数据结构服务器。</p><p>Redis的作者是Salvatore Sanfillippo,来自意大利的西西里岛,现在居住在卡塔尼亚。目前供职于Pivotal公司(Pivotal是Spring框架的开发团队),Salvatore Sanfilippo被称为Redis之父。<br><img src="/images/redis/redis01.png" alt="Redis之父Salvatore Sanfillippo"><br>官网:<a href="https://redis.io/" target="_blank" rel="noopener">https://redis.io/</a><br>中文:<a href="http://www.redis.cn/" target="_blank" rel="noopener">http://www.redis.cn/</a></p><h3 id="Redis的历史"><a href="#Redis的历史" class="headerlink" title="Redis的历史:"></a>Redis的历史:</h3><p>2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统LLOOGG,然而没过多久该公司的创始人Salvatore Sanfilippo便开始对MySQL的性能感到失望,于是他决定亲自为LLOOGG量身定做一个数据库,并与2009年完成,这个数据库就是Redis。</p><p>不过Salvatore Sanfilippo并不满足只将Redis用于LLOOGG这一款产品,而是希望让更多的人使用它,于是在同一年Salvatore Sanfilippo将Redis开源发布,并开始和Redis的另一名主要的代码贡献者Pieter Noordhuis一起继续着Redis的开发,直到今天。</p><p>Sanfilippo Salvatore自己也没有想到,短短的几年时间,Redis就拥有了庞大的用户群体。2012年数据库的使用情况调查,结果显示有近12%的公司在使用Redis。国内如新浪微博、知乎,国外如GitHub、Stack Overflow、Flickr、暴雪和Instagram,都是Redis的用户。</p><p>VMware公司从2010年开始赞助Redis的开发,Salvatore Sanfilippo和Pieter Noordhuis也分别于同年的3月和5月加入VMware,全职开发Redis。</p><p>Redis的代码托管在Github上<a href="https://github.com/antirez/redis" title="redis" target="_blank" rel="noopener">https://github.com/antirez/redis</a>,开发十分活跃,代码量只有三万多行。</p><h3 id="Windows-上安装Redis"><a href="#Windows-上安装Redis" class="headerlink" title="Windows 上安装Redis"></a>Windows 上安装Redis</h3><p>Windows版本的Redis是Microsoft的开源部门提供的Redis。这个版本的Redis适合开发人员学习使用,生产环境中使用Linux系统上的Redis。</p><h4 id="下载"><a href="#下载" class="headerlink" title="下载"></a>下载</h4><p><a href="https://redis.io/" title="redis" target="_blank" rel="noopener">官网:https://redis.io/</a><br><a href="https://github.com/MSOpenTech/redis/releases" title="redis" target="_blank" rel="noopener">windows版本:https://github.com/MSOpenTech/redis/releases</a></p><p><img src="/images/redis/redis02.png" alt="windows版redis下载"></p><h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><p>下载的Redis-x64-3.2.100.zip解压后,放到某个目录(例如D:\redis\),即可使用。目录结构:<br><img src="/images/redis/redis03.png" alt="redis目录结构"></p><h4 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h4><p>A、 Windows7系统双击redis-server.exe启动Redis<br><img src="/images/redis/redis04.png" alt="redis启动"><br>B、 Win10系统<br>有的机器双击redis-server.exe执行失败,找不到配置文件,可以采用以下执行方式:在命令行(cmd)中按如下方式执行D:\Redis&gt;redis-server.exe redis.windows.conf<br>如图:<br><img src="/images/redis/redis05.png" alt="redis启动"></p><h4 id="关闭"><a href="#关闭" class="headerlink" title="关闭"></a>关闭</h4><p>按ctrl+c退出Redis服务程序。</p><h4 id="添加到服务"><a href="#添加到服务" class="headerlink" title="添加到服务"></a>添加到服务</h4><p>添加:redis-server.exe –service-install redis.windows.conf –service-name redis –port 6379<br>删除:sc delete redis<br>启动:net start redis<br>停止:net stop redis</p><p>当然,由于windows版本redis出现的背景原因,建议在windows下只是测试和学习使用,生产环境最好还是在linux系统下使用。</p><h3 id="Linux-上安装Redis"><a href="#Linux-上安装Redis" class="headerlink" title="Linux 上安装Redis"></a>Linux 上安装Redis</h3><h4 id="下载-1"><a href="#下载-1" class="headerlink" title="下载"></a>下载</h4><p>wget <a href="http://download.redis.io/releases/redis-5.0.3.tar.gz" target="_blank" rel="noopener">http://download.redis.io/releases/redis-5.0.3.tar.gz</a></p><h4 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h4><p>解压缩redis-5.0.3.tar.gz到usr/local目录<br><img src="/images/redis/redis06.png" alt="redis安装"><br>查看解压缩后的文件<br><img src="/images/redis/redis07.png" alt="redis安装"><br>编译Redis文件,Redis是使用C语言编写的。会使用gcc编译器。<br>在解压后的Redis目下执行(cd /usr/local/redis-5.0.3)make命令。</p><p>注意事项:<br>1) make命令执行过程中可能保存,根据控制台数据的错误信息进行解决<br>2) 错误一: gcc命令找不到,是由于没有安装gcc导致<br>解决方式:安装gcc编译器后在执行make命令。<br>什么是gcc?<br>gcc是GNU compiler collection的缩写,它是linux下一个编辑器集合(相当于javac),是c或c++程序的编译器。<br>怎么安装gcc?<br>使用yum进行安装gcc。执行命令: yum -y install gcc<br>3) 错误二: error:jemalloc/jemalloc.h: No such file or directory<br>解决方式执行make MALLOC=libc</p><p>开始执行make<br>注意:在make执行之后再执行make install,该操作则将src下的许多可执行文件复制/usr/local/bin目录下,这样做可以在任意目录执行redis的软件的命令(例如启动,停止,客户端连接服务器等),make install可以不用执行,看个人习惯。</p><p>查看make编译结果,cd src目录<br><img src="/images/redis/redis08.png" alt="redis编译"><br>cd src在执行ls<br><img src="/images/redis/redis09.png" alt="redis编译"></p><h4 id="启动Redis"><a href="#启动Redis" class="headerlink" title="启动Redis"></a>启动Redis</h4><p>前台启动 ./redis-server<br>后台启动 ./redis-server &amp;<br>查看redis启动进程 ps -ef | grep redis</p><h4 id="关闭Redis"><a href="#关闭Redis" class="headerlink" title="关闭Redis"></a>关闭Redis</h4><p>关闭方式:<br>1) 使用redis客户端关闭,向服务器发出关闭命令。切换到redis-3.2.9/src/目录,执行./redis-cli shutdown<br>推荐使用这种方式,redis先完成数据操作,然后再关闭。<br>例如:<br><img src="/images/redis/redis10.png" alt="redis关闭"><br>2) kill pid或者kill -9 pid<br>这种不会考虑当前应用是否有数据库正在执行操作,直接就关闭应用。<br>先使用ps -ef | grep redis查出进程号,在使用kill pid<br><img src="/images/redis/redis11.png" alt="redis关闭"></p><h3 id="Redis客户端"><a href="#Redis客户端" class="headerlink" title="Redis客户端"></a>Redis客户端</h3><p>Redis客户端是一个程序,通过网络连接到Redis服务器,在客户端软件中使用Redis可以识别的命令,向Redis服务器发送命令,告诉Redis想要做什么。Redis把处理结果显示在客户端界面上。通过Redis客户端和Redis服务器交互。<br>Redis客户端发送命令,同时显示Redis服务器的处理结果。</p><h4 id="redis命令行客户端:"><a href="#redis命令行客户端:" class="headerlink" title="redis命令行客户端:"></a>redis命令行客户端:</h4><p>redis-cli(Redis Command Line Interface)是Redis自带的基于命令行的Redis客户端,用于与服务器端交互,我们可以使用该客户端来执行redis锋各种命令。两种常用的连接方式:</p><p>A、 直接连接redis(默认ip127.0.0.1,端口6379): ./redis-cli<br>在redis安装目录\src,执行./redis-cli<br>此命令式连接本机127.0.0.1,端口6379的redis</p><p>B、 指定IP和端口连接redis: ./redis-cli -h 127.0.0.1 -p 6379<br>-h redis 主机 IP(可以指定任意的redis服务器)<br>-p 端口号(不同端口表示不同的应用)</p><h4 id="redis远程客户端"><a href="#redis远程客户端" class="headerlink" title="redis远程客户端"></a>redis远程客户端</h4><p>Redis Desktop Manager: C++编写,响应迅速,性能好。<br><a href="https://redisdesktop.com/" title="Redis Desktop Manager" target="_blank" rel="noopener">官网地址: https://redisdesktop.com/</a><br><a href="https://github.com/uglide/RedisDesktopManager" title="Redis Desktop Manager github" target="_blank" rel="noopener">github: https://github.com/uglide/RedisDesktopManager</a><br><a href="http://docs.redisdesktop.com/en/latest/" title="使用文档" target="_blank" rel="noopener">使用文档: http://docs.redisdesktop.com/en/latest/</a><br><img src="/images/redis/redis12.png" alt="Redis Desktop Manager"><br>点击 “DOWNLOAD”<br><img src="/images/redis/redis13.png" alt="Redis Desktop Manager"></p><h5 id="安装客户端软件"><a href="#安装客户端软件" class="headerlink" title="安装客户端软件"></a>安装客户端软件</h5><p>在windows系统使用此工具,连接Linux上或Windows上的Redis,双击此exe文件执行安装。<br><img src="/images/redis/redis14.png" alt="Redis Desktop Manager"><br>安装后启动界面:<br><img src="/images/redis/redis15.png" alt="Redis Desktop Manager"></p><h5 id="使用客户端连接Linux的Redis"><a href="#使用客户端连接Linux的Redis" class="headerlink" title="使用客户端连接Linux的Redis"></a>使用客户端连接Linux的Redis</h5><p>连接Linux的Redis之前需要修改Redis服务器的配置信息。Redis服务器有安全保护措施,默认只有本机(安装Redis的那台机器)能够访问。配置信息存放在Redis安装目录下的redis.conf文件。修改此文件的两个设置。<br>远程连接redis需要修改redis注目下的redis.conf配置文件:<br>1) bing ip 绑定ip此行注释<br>2)protected-mode yes 保护模式改为no<br>使用vim命令修改redis.conf文件,修改此文件前备份此文件,执行cp命令<br><img src="/images/redis/redis16.png" alt="Redis配置"><br>执行vm redis.conf<br><img src="/images/redis/redis17.png" alt="Redis配置"></p><h5 id="使用redis-conf启动redis"><a href="#使用redis-conf启动redis" class="headerlink" title="使用redis.conf启动redis"></a>使用redis.conf启动redis</h5><p>修改配置文件后,需要使用配置文件重新启动Redis,默认不加载配置文件。先关闭已启动的Redis,使用一下命令启动Redis在Redis安装目录执行:<br>./redis-server ../redis.conf &amp;<br><img src="/images/redis/redis18.png" alt="Redis配置"></p><h5 id="配置Redis-Desktop-Manager-RDM-连接Redis"><a href="#配置Redis-Desktop-Manager-RDM-连接Redis" class="headerlink" title="配置Redis Desktop Manager(RDM),连接Redis"></a>配置Redis Desktop Manager(RDM),连接Redis</h5><p>在RDM的主窗口,点击左下的”Connect to Redis Server”<br><img src="/images/redis/redis19.png" alt="Redis"><br>连接成功后:<br><img src="/images/redis/redis20.png" alt="Redis"></p><h4 id="redis编程客户端"><a href="#redis编程客户端" class="headerlink" title="redis编程客户端"></a>redis编程客户端</h4><h5 id="Jedis"><a href="#Jedis" class="headerlink" title="Jedis"></a>Jedis</h5><p>redis的Java编程客户端,Redis官方首先推荐使用Jedis,jedis是一个很小但很健全的redis的Java客户端。通过Jedis可以像使用Redis命令行一样使用Redis。</p><ul><li>jedis完全兼容redis 2.8.x and 3.x.x</li><li>jedis源码: <a href="https://github.com/xetorthio/jedis" target="_blank" rel="noopener">https://github.com/xetorthio/jedis</a></li><li>api文档: <a href="http://xetorthio.github.io/jedis/" target="_blank" rel="noopener">http://xetorthio.github.io/jedis/</a></li></ul><h5 id="redis的其他编程语言客户端"><a href="#redis的其他编程语言客户端" class="headerlink" title="redis的其他编程语言客户端"></a>redis的其他编程语言客户端</h5><p>C、C++、C#、Erlang、Lua、Objective-C、Perl、PHP、Python、Ruby、Scala、Go等40多种语言都有连接redis的编程客户端。</p><h3 id="Redis的基本操作命令"><a href="#Redis的基本操作命令" class="headerlink" title="Redis的基本操作命令"></a>Redis的基本操作命令</h3><p>redis默认为16个库(在redis.conf文件可以配置,该文件很重要,后续很多操作都是这个配置文件)redis默认自动使用0号库。</p><h4 id="沟通命令,查看状态"><a href="#沟通命令,查看状态" class="headerlink" title="沟通命令,查看状态"></a>沟通命令,查看状态</h4><p>redis&gt;ping 返回PONG<br>解释: 输入ping,redis给我们返回PONG,表示redis服务运行正常。<br><img src="/images/redis/redis21.png" alt="Redis"></p><h4 id="查看当前数据库中的key的数目:dbsize"><a href="#查看当前数据库中的key的数目:dbsize" class="headerlink" title="查看当前数据库中的key的数目:dbsize"></a>查看当前数据库中的key的数目:dbsize</h4><p>语法:dbsize<br>作用:返回当前数据库的key的数量。<br>返回值:数字,key的数量<br>例:先查索引5的key个数,在查0库的key个数<br><img src="/images/redis/redis22.png" alt="Redis"></p><h4 id="redis默认使用16个库"><a href="#redis默认使用16个库" class="headerlink" title="redis默认使用16个库"></a>redis默认使用16个库</h4><p>Redis默认使用16个库,从0到15。对数据库个数的修改,在redis.conf文件中databases 16<br><img src="/images/redis/redis23.png" alt="Redis"></p><h4 id="切换库命令-select-db"><a href="#切换库命令-select-db" class="headerlink" title="切换库命令: select db"></a>切换库命令: select db</h4><p>使用其他数据库,命令是select index<br>例如:select 5<br><img src="/images/redis/redis24.png" alt="Redis"></p><h4 id="删除当前库的数据-flushdb"><a href="#删除当前库的数据-flushdb" class="headerlink" title="删除当前库的数据:flushdb"></a>删除当前库的数据:flushdb</h4><p><img src="/images/redis/redis25.png" alt="Redis"></p><h4 id="redis自带的客户端退出当前redis连接-exit或quit"><a href="#redis自带的客户端退出当前redis连接-exit或quit" class="headerlink" title="redis自带的客户端退出当前redis连接:exit或quit"></a>redis自带的客户端退出当前redis连接:exit或quit</h4><p><img src="/images/redis/redis26.png" alt="Redis"></p><h3 id="Redis的Key的操作命令"><a href="#Redis的Key的操作命令" class="headerlink" title="Redis的Key的操作命令"></a>Redis的Key的操作命令</h3><h4 id="keys-pattern"><a href="#keys-pattern" class="headerlink" title="keys pattern"></a>keys pattern</h4><p>作用: 查找所有符合模式pattern的key。pattern可以使用通配符。<br>通配符:</p><ul><li>*:表示0-多个字符,例如:keys *查询所有key。</li><li>?:表示单个字符,例如:wo?d,匹配word,wood等。</li></ul><p>例1:显示所有的key<br><img src="/images/redis/redis27.png" alt="Redis"><br>例2:使用*表示0或多个字符<br><img src="/images/redis/redis28.png" alt="Redis"><br>例3:使用?表示单个字符<br><img src="/images/redis/redis29.png" alt="Redis"></p><h4 id="exists"><a href="#exists" class="headerlink" title="exists"></a>exists</h4><p>语法:exists key [key···]<br>作用:判断key是否存在<br>返回值:整数,存在key返回1,其他返回0。使用多个key,返回存在的key的数量。<br>例1:检查指定key是否存在<br><img src="/images/redis/redis30.png" alt="Redis"><br>例2:检查多个key<br><img src="/images/redis/redis31.png" alt="Redis"></p><h4 id="expire"><a href="#expire" class="headerlink" title="expire"></a>expire</h4><p>语法:expire key seconds<br>作用:设置key的生存时间,超过时间,key自动删除。单位是秒。<br>返回值:设置成功返回数字1,其他情况是0。<br>例1: 设置红灯的倒计时是5秒<br><img src="/images/redis/redis32.png" alt="Redis"></p><h4 id="ttl"><a href="#ttl" class="headerlink" title="ttl"></a>ttl</h4><p>语法:ttl key<br>作用:以秒为单位,返回key的剩余生存时间(ttl:time to live)<br>返回值:</p><ul><li>-1:没有设置key的生存时间,key永不过期。</li><li>-2:key不存在</li><li>数字:key的剩余时间,秒为单位。<br>例1:设置redlight的过期时间是10s,查看剩余时间<br><img src="/images/redis/redis33.png" alt="Redis"></li></ul><h4 id="type"><a href="#type" class="headerlink" title="type"></a>type</h4><p>语法:type key<br>作用:查看key所存储值得数据类型<br>返回值:字符串表示的数据类型</p><ul><li>none(key不存在)</li><li>string(字符串)</li><li>list(列表)</li><li>set(集合)</li><li>zset(有序集)</li><li>hash(哈希表)</li></ul><p>例1:查看存储字符串的key: wood<br><img src="/images/redis/redis34.png" alt="Redis"><br>例2:查看不存在的key<br><img src="/images/redis/redis35.png" alt="Redis"></p><h4 id="del"><a href="#del" class="headerlink" title="del"></a>del</h4><p>语法:del key [key···]<br>作用:删除存在的key,不存在的key忽略。<br>返回值:数字,删除的key的数量。</p><p>例1:删除指定的key<br><img src="/images/redis/redis36.png" alt="Redis"></p><h3 id="Redis的5种数据类型"><a href="#Redis的5种数据类型" class="headerlink" title="Redis的5种数据类型"></a>Redis的5种数据类型</h3><h4 id="字符串类型-string"><a href="#字符串类型-string" class="headerlink" title="字符串类型 string"></a>字符串类型 string</h4><p>字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据,序列化后的数据,JSON化的对象甚至是一张图片。最大512M。<br><img src="/images/redis/redis37.png" alt="Redis"></p><h4 id="哈希类型-hash"><a href="#哈希类型-hash" class="headerlink" title="哈希类型 hash"></a>哈希类型 hash</h4><p>Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。<br><img src="/images/redis/redis38.png" alt="Redis"></p><h4 id="列表类型-list"><a href="#列表类型-list" class="headerlink" title="列表类型 list"></a>列表类型 list</h4><p>Redis列表时简单的字符串类别,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。<br><img src="/images/redis/redis39.png" alt="Redis"></p><h4 id="集合类型-set"><a href="#集合类型-set" class="headerlink" title="集合类型 set"></a>集合类型 set</h4><p>Redis的Set是string类型的无序集合,集合成员是唯一的,即集合中不能出现重复数据。<br><img src="/images/redis/redis40.png" alt="Redis"></p><h4 id="有序集合类型-zset-sorted-set"><a href="#有序集合类型-zset-sorted-set" class="headerlink" title="有序集合类型 zset(sorted set)"></a>有序集合类型 zset(sorted set)</h4><p>Redis有序集合zset和集合set一样是string类型元素的集合,且不允许重复的成员。不同的是zset的每个元素都会关联一个分数(分数可以重复),redis通过分数来为集合中的成员进行从小到大的排序。<br><img src="/images/redis/redis41.png" alt="Redis"></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Redis安装和使用&quot;&gt;&lt;a href=&quot;#Redis安装和使用&quot; class=&quot;headerlink&quot; title=&quot;Redis安装
</summary>
<category term="数据库" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Redis" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/"/>
<category term="Redis" scheme="http://smartdot.club/tags/Redis/"/>
</entry>
<entry>
<title>第1课 flowable</title>
<link href="http://smartdot.club/%E5%B7%A5%E4%BD%9C%E6%B5%81/Flowable/%E7%AC%AC10%E8%AF%BE%20flowable%E5%B7%A5%E4%BD%9C%E6%B5%81/"/>
<id>http://smartdot.club/工作流/Flowable/第10课 flowable工作流/</id>
<published>2019-02-27T12:17:09.000Z</published>
<updated>2019-02-27T08:54:43.730Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Shiro简介"><a href="#Shiro简介" class="headerlink" title="Shiro简介"></a>Shiro简介</h2><ul><li>Apache Shiro是Java的一个安全(权限)框架。</li><li>Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。</li><li>Shiro可以完成:认证、授权、加密、会话管理、与Web集成、缓存等。</li><li>下载: <a href="http://shiro.apache.org/" target="_blank" rel="noopener">http://shiro.apache.org/</a></li></ul><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Shiro简介&quot;&gt;&lt;a href=&quot;#Shiro简介&quot; class=&quot;headerlink&quot; title=&quot;Shiro简介&quot;&gt;&lt;/a&gt;
</summary>
<category term="工作流" scheme="http://smartdot.club/categories/%E5%B7%A5%E4%BD%9C%E6%B5%81/"/>
<category term="Flowable" scheme="http://smartdot.club/categories/%E5%B7%A5%E4%BD%9C%E6%B5%81/Flowable/"/>
<category term="Flowable" scheme="http://smartdot.club/tags/Flowable/"/>
</entry>
<entry>
<title>第2课 flowable工作流概念</title>
<link href="http://smartdot.club/%E5%B7%A5%E4%BD%9C%E6%B5%81/Flowable/%E7%AC%AC1%E8%AF%BE%20flowable%E5%B7%A5%E4%BD%9C%E6%B5%81%E6%A6%82%E5%BF%B5/"/>
<id>http://smartdot.club/工作流/Flowable/第1课 flowable工作流概念/</id>
<published>2019-02-27T12:17:09.000Z</published>
<updated>2019-02-27T08:53:07.983Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Shiro简介"><a href="#Shiro简介" class="headerlink" title="Shiro简介"></a>Shiro简介</h2><ul><li>Apache Shiro是Java的一个安全(权限)框架。</li><li>Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。</li><li>Shiro可以完成:认证、授权、加密、会话管理、与Web集成、缓存等。</li><li>下载: <a href="http://shiro.apache.org/" target="_blank" rel="noopener">http://shiro.apache.org/</a></li></ul><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Shiro简介&quot;&gt;&lt;a href=&quot;#Shiro简介&quot; class=&quot;headerlink&quot; title=&quot;Shiro简介&quot;&gt;&lt;/a&gt;
</summary>
<category term="工作流" scheme="http://smartdot.club/categories/%E5%B7%A5%E4%BD%9C%E6%B5%81/"/>
<category term="Flowable" scheme="http://smartdot.club/categories/%E5%B7%A5%E4%BD%9C%E6%B5%81/Flowable/"/>
<category term="Flowable" scheme="http://smartdot.club/tags/Flowable/"/>
</entry>
<entry>
<title>第1章 NoSQL</title>
<link href="http://smartdot.club/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/%E7%AC%AC1%E7%AB%A0%20NoSQL/"/>
<id>http://smartdot.club/数据库/Redis/第1章 NoSQL/</id>
<published>2019-02-27T12:17:09.000Z</published>
<updated>2019-03-06T14:51:46.758Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="NoSQL"><a href="#NoSQL" class="headerlink" title="NoSQL"></a>NoSQL</h2><h3 id="什么是NoSQL"><a href="#什么是NoSQL" class="headerlink" title="什么是NoSQL"></a>什么是NoSQL</h3><p>NoSQL = Not Only SQL(不仅仅是SQL),也解释为non-relational(非关系型数据库)。在NoSQL数据库中数据之间是无联系的,无关系的。数据的结构是松散的,可变的。</p><h3 id="为什么使用NoSQL"><a href="#为什么使用NoSQL" class="headerlink" title="为什么使用NoSQL"></a>为什么使用NoSQL</h3><p>关系型数据库的瓶颈:</p><p>1) 无法应对每秒上万次的读写请求,无法处理大量集中的高并发操作。关系型数据的IO密集的应用。硬盘IO也变为性能瓶颈。<br>2) 存储记录数量有限,横向可扩展能力有限,一张表最大两百多列。纵向数据可承受的能力也是有限的,一张表的数据到达百万级,读写的速度就会逐渐的下降。面对海量数据必须使用主从复制,分库分表。这样的系统架构是难以维护的。<br>3) 无法简单地通过增加硬件、服务节点来提高系统性能。数据整个存储在一个数据库中的。多个服务器没有很好的解决办法,来复制这些数据。<br>4) 关系型数据库大多是收费的,对硬件的要求比较高。软件和硬件的成本花费比较重大。</p><h3 id="NoSQL的优势"><a href="#NoSQL的优势" class="headerlink" title="NoSQL的优势"></a>NoSQL的优势</h3><p>(1) 大数据量,高性能<br>NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。关系型数据库(例如MySQL)使用查询缓存。这种查询缓存在更新数据库后,缓存就是失效的。在频繁的数据读写交互应用中。缓存的性能不高。NoSQL的缓存性能要高的多。</p><p>(2) 灵活的数据模型<br>NoSQL无需事先为要缓存的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。尤其在快速变化的市场环境中,用户的需求总是在不断变化的。</p><p>(3) 高可用<br>NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。</p><p>NoSQL能很好的解决关系型数据库扩展性差的问题。弥补了关系数据库(比如MySQL)在某些方面的不足,在某些方面能极大的节省开发成本和维护成本。</p><p>MySQL和NoSQL都有各自的特点和使用的应用场景,两者结合使用。让关系数据库关注在关系上,NoSQL关注在存储上。</p><p>(4) 低成本<br>这是大多数分布式数据库共有的特点,因为主要都是开源软件,没有昂贵的License成本。</p><h3 id="NoSQL的劣势"><a href="#NoSQL的劣势" class="headerlink" title="NoSQL的劣势"></a>NoSQL的劣势</h3><p>(1) 无关系,数据之间是无联系的。<br>(2) 不支持标准的SQL,没有公认的NoSQL标准。<br>(3) 没有关系型数据库的约束,大多数也没有索引的概念。<br>(4) 没有事务,不能依靠事务实现ACID。<br>(5) 没有丰富的数据类型(数值,日期,字符,二进制,大文本等)</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;NoSQL&quot;&gt;&lt;a href=&quot;#NoSQL&quot; class=&quot;headerlink&quot; title=&quot;NoSQL&quot;&gt;&lt;/a&gt;NoSQL&lt;
</summary>
<category term="数据库" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="Redis" scheme="http://smartdot.club/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/Redis/"/>
<category term="Redis" scheme="http://smartdot.club/tags/Redis/"/>
</entry>
<entry>
<title>01 VMware Workstation Pro网络Nat模式配置</title>
<link href="http://smartdot.club/Linux/01_VMware%20Workstation%20Pro%E7%BD%91%E7%BB%9CNat%E6%A8%A1%E5%BC%8F%E9%85%8D%E7%BD%AE/"/>
<id>http://smartdot.club/Linux/01_VMware Workstation Pro网络Nat模式配置/</id>
<published>2018-12-28T03:11:54.000Z</published>
<updated>2019-02-27T08:43:24.219Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="VMware-Workstation-Pro网络Nat模式配置"><a href="#VMware-Workstation-Pro网络Nat模式配置" class="headerlink" title="VMware Workstation Pro网络Nat模式配置"></a>VMware Workstation Pro网络Nat模式配置</h2><h3 id="前景"><a href="#前景" class="headerlink" title="前景"></a>前景</h3><blockquote><p>我的目标是虚拟机可以上外网并且可以和主机进行通信,主机可以和虚拟机通信,和主机在局域网的机器可以通过端口转换访问主机的虚拟机中的机器。<br>由于桥接模式必须主机电脑连接网路由于我电脑偶尔会在断网情况下工作,因此这里只能选择Nat模式。<br>主机:主机电脑IP地址为:192.168.1.25(这个其实并不影响什么)<br>虚拟机: 默认网关192.168.6.2<br>虚拟机01: 192.168.6.3<br>虚拟机02: 192.168.6.4<br>虚拟机03: 192.168.6.5<br>···</p></blockquote><h3 id="Mware-Workstation-Pro网络Nat模式配置"><a href="#Mware-Workstation-Pro网络Nat模式配置" class="headerlink" title="Mware Workstation Pro网络Nat模式配置"></a>Mware Workstation Pro网络Nat模式配置</h3><p>首先,点击编辑按钮,选择虚拟机网络编辑器。如下图:</p><blockquote><p><img src="/images/linux/01-vm01.png" alt="avatar"></p></blockquote><p>其次,选择VMnet8,修改类型为Nat模式,更改子网IP,点击更改设置,设置子网IP为:192.168.6.0, 子网掩码为:255.255.255.0</p><blockquote><p><img src="/images/linux/01-vm02.png" alt="avatar"></p></blockquote><p>然后,修改默认网关(一般情况下修改好子网IP后默认网关自动回配置好)。点击Nat设置,修改网关IP为192.168.6.2即可。</p><blockquote><p><img src="/images/linux/01-vm03.png" alt="avatar"></p></blockquote><h3 id="主机局域网内访问虚拟机应用"><a href="#主机局域网内访问虚拟机应用" class="headerlink" title="主机局域网内访问虚拟机应用"></a>主机局域网内访问虚拟机应用</h3><blockquote><p>我在虚拟机里通过Gogs搭建了一个git服务器,<br>虚拟机环境为centos6,<br>设置的静态IP地址为:192.168.6.3。<br>主机可以通过<a href="http://192.168.6.3:10000去访问我的git仓库," target="_blank" rel="noopener">http://192.168.6.3:10000去访问我的git仓库,</a><br>但是主机同局域网内的其他机器则不能访问。因此,我需要配置端口转发功能。<br>点击Nat设置,在端口转发下面选择添加,主机端口选择一个没有应用占用的端口即可,这里我选择9999,类型选择TCP,<br>虚拟机IP地址这里我自然选择192.168.6.3,可以填或者不写,这里描述我简单写为Gogs搭建的git仓库,然后点击确定就好。<br>最后测试,主机内局域网的机器顺利通过192.168.1.25:9999访问虚拟机(192.168.6.3:10000)中的gogs服务。<br>注意:192.168.1.25是我当前主机的IP的值,可通过IpConfig查看当前IP4地址。<br>当前,主机也可以通过<a href="http://192.168.1.25:9999或者http://192.168.6.3:10000,或者http://127.0.0.1:9999进行访问Gogs应用。" target="_blank" rel="noopener">http://192.168.1.25:9999或者http://192.168.6.3:10000,或者http://127.0.0.1:9999进行访问Gogs应用。</a><br>确保Windows服务启动项中,“VMware DHCP Service”、”VMware NAT Service”,两项服务是否启动</p></blockquote><h3 id="Linux下静态IP配置"><a href="#Linux下静态IP配置" class="headerlink" title="Linux下静态IP配置"></a>Linux下静态IP配置</h3><h4 id="cenots7-6下静态IP配置"><a href="#cenots7-6下静态IP配置" class="headerlink" title="cenots7.6下静态IP配置"></a>cenots7.6下静态IP配置</h4><p>首先,编辑etc/sysconfig/network-scripts/ifcfg-ens33文件</p><blockquote><p>[caifenglin@caifenglin /]$ vim etc/sysconfig/network-scripts/ifcfg-ens33</p><p>TYPE=Ethernet<br>PROXY_METHOD=none<br>BROWSER_ONLY=no<br>BOOTPROTO=static<br>DEFROUTE=yes<br>IPV4_FAILURE_FATAL=no<br>IPV6INIT=yes<br>IPV6_AUTOCONF=yes<br>IPV6_DEFROUTE=yes<br>IPV6_FAILURE_FATAL=no<br>IPV6_ADDR_GEN_MODE=stable-privacy<br>NAME=ens33<br>UUID=7533c908-1b34-4d82-a7f2-ab7bd4ac8838<br>DEVICE=ens33<br>ONBOOT=yes<br>IPADDR=192.168.6.4<br>NETMASK=255.255.255.0<br>NETWORK=192.168.6.2<br>DNS1=192.168.1.1<br>DNS2=8.8.8.8</p></blockquote><p>其次,修改/etc/sysconfig/network,配置网关,否则无法上网</p><blockquote><p>[caifenglin@caifenglin /]$ vim /etc/sysconfig/network</p><p>#Created by anaconda<br>NETWORKING=yes<br>GATEWAY=192.168.6.2<br>DNS1=192.168.1.1<br>DNS2=8.8.8.8</p></blockquote><p>重启网路服务</p><blockquote><p>service network restart</p></blockquote><h4 id="centos6-9下配置静态IP"><a href="#centos6-9下配置静态IP" class="headerlink" title="centos6.9下配置静态IP"></a>centos6.9下配置静态IP</h4><p>首先,编辑etc/sysconfig/network-scripts/ifcfg-ens33文件</p><blockquote><p>[caifenglin@suixin network-scripts]$ vim /etc/sysconfig/network-scripts/ifcfg-eth0</p><p>DEVICE=eth0<br>HWADDR=00:0C:29:97:FF:A5<br>TYPE=Ethernet<br>UUID=56cd27b3-48e7-453e-a365-cf1075ad70e5<br>ONBOOT=yes<br>NM_CONTROLLED=yes<br>BOOTPROTO=static<br>IPADDR=192.168.6.3<br>NETMASK=255.255.255.0<br>GATEWAY=192.168.6.2<br>DNS1=192.168.1.1<br>DNS2=114.114.114.114</p></blockquote><p>其次,修改/etc/resolv.conf 配置DNS</p><blockquote><p>[caifenglin@suixin network-scripts]$ vim /etc/resolv.conf</p><p># Generated by NetworkManager<br>nameserver 192.168.1.1<br>nameserver 114.114.114.114</p></blockquote><p>最后,重启网路服务</p><blockquote><p>运行”service network restart”命令,重启网络服务,使刚才修改的配置信息生效</p></blockquote><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;VMware-Workstation-Pro网络Nat模式配置&quot;&gt;&lt;a href=&quot;#VMware-Workstation-Pro网络
</summary>
<category term="Linux" scheme="http://smartdot.club/categories/Linux/"/>
<category term="Linux" scheme="http://smartdot.club/tags/Linux/"/>
</entry>
<entry>
<title>Jetty学习上</title>
<link href="http://smartdot.club/Jetty/Jetty%E5%AD%A6%E4%B9%A0%E4%B8%8A/"/>
<id>http://smartdot.club/Jetty/Jetty学习上/</id>
<published>2018-08-19T12:17:09.000Z</published>
<updated>2019-02-27T08:43:24.217Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="Jetty大纲视图"><a href="#Jetty大纲视图" class="headerlink" title="Jetty大纲视图"></a>Jetty大纲视图</h2><p><img src="/images/jetty/jetty01.png" alt="Jetty大纲视图"></p><h2 id="什么是Jetty"><a href="#什么是Jetty" class="headerlink" title="什么是Jetty?"></a>什么是Jetty?</h2><p>简单来讲 Jetty就是一个开源的HTTP服务器和Servlet引擎,它可以为JSP和Servlet提供运行时环境。比如Java Web应用最常见的Servlet容器Tomcat。由于其轻量级、灵活的特性,Jetty也被应用于一些知名产品中,例如ActiveMQ、Maven、Spark、GoogleAppEngine、Eclipse、Hadoop等。</p><h2 id="为什么使用Jetty"><a href="#为什么使用Jetty" class="headerlink" title="为什么使用Jetty?"></a>为什么使用Jetty?</h2><p>异步的Servlet,支持更高的并发量<br>模块化的设计,更灵活,更容易定制,也意味着更高的资源利用率<br>在面对大量的长连接的业务场景下,Jetty默认采用的NIO模型是更好的选择<br>将Jetty嵌入到应用中,使一个普通应用可以快速支持http服务<br><a id="more"></a></p><h2 id="Jeety的基本架构"><a href="#Jeety的基本架构" class="headerlink" title="Jeety的基本架构"></a>Jeety的基本架构</h2><p>Jetty的架构比较简单,核心组件主要是由Servlet和Handle组成。其中Server的Handler是其比较重要的一个数据模型,Jetty中所有的组件都是基于Handler。<br><img src="/images/jetty/jetty02.png" alt="Jetty基本架构"></p><h2 id="与tomcat对比"><a href="#与tomcat对比" class="headerlink" title="与tomcat对比"></a>与tomcat对比</h2><p>Jetty比较容易贴合第三方框架,比如你可以直接用spring配置一个Jetty服务<br>直接将Jetty作为提供HTTP服务的组件,嵌入到应用中<br>Jetty是面向Handle的架构,而Tomcat是面向容器的架构<br>Jetty默认采用NIO技术 ,而Tomcat默认是BIO<br>Jetty高度模块化,可以很灵活的管理扩展组件,而Tomcat对其他组件的管理则相对困难</p><p>Tomcat架构图如下:<br><img src="/images/jetty/jetty03.png" alt="Tomcat基本架构"></p><h2 id="使用Jetty"><a href="#使用Jetty" class="headerlink" title="使用Jetty"></a>使用Jetty</h2><p><img src="/images/jetty/jetty04.png" alt="Jetty版本"><br><img src="/images/jetty/jetty05.png" alt="Jetty目录"></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;Jetty大纲视图&quot;&gt;&lt;a href=&quot;#Jetty大纲视图&quot; class=&quot;headerlink&quot; title=&quot;Jetty大纲视图&quot;&gt;&lt;/a&gt;Jetty大纲视图&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;/images/jetty/jetty01.png&quot; alt=&quot;Jetty大纲视图&quot;&gt;&lt;/p&gt;&lt;h2 id=&quot;什么是Jetty&quot;&gt;&lt;a href=&quot;#什么是Jetty&quot; class=&quot;headerlink&quot; title=&quot;什么是Jetty?&quot;&gt;&lt;/a&gt;什么是Jetty?&lt;/h2&gt;&lt;p&gt;简单来讲 Jetty就是一个开源的HTTP服务器和Servlet引擎,它可以为JSP和Servlet提供运行时环境。比如Java Web应用最常见的Servlet容器Tomcat。由于其轻量级、灵活的特性,Jetty也被应用于一些知名产品中,例如ActiveMQ、Maven、Spark、GoogleAppEngine、Eclipse、Hadoop等。&lt;/p&gt;&lt;h2 id=&quot;为什么使用Jetty&quot;&gt;&lt;a href=&quot;#为什么使用Jetty&quot; class=&quot;headerlink&quot; title=&quot;为什么使用Jetty?&quot;&gt;&lt;/a&gt;为什么使用Jetty?&lt;/h2&gt;&lt;p&gt;异步的Servlet,支持更高的并发量&lt;br&gt;模块化的设计,更灵活,更容易定制,也意味着更高的资源利用率&lt;br&gt;在面对大量的长连接的业务场景下,Jetty默认采用的NIO模型是更好的选择&lt;br&gt;将Jetty嵌入到应用中,使一个普通应用可以快速支持http服务&lt;br&gt;
</summary>
<category term="Jetty" scheme="http://smartdot.club/categories/Jetty/"/>
<category term="Jetty" scheme="http://smartdot.club/tags/Jetty/"/>
</entry>
<entry>
<title>专题:SVN版本控制技术</title>
<link href="http://smartdot.club/%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6/SVN/SVN%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6%E6%8A%80%E6%9C%AF%E4%B8%93%E9%A2%98/"/>
<id>http://smartdot.club/版本控制/SVN/SVN版本控制技术专题/</id>
<published>2018-05-09T12:01:03.000Z</published>
<updated>2019-02-27T08:43:24.231Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="第1章-SVN概述"><a href="#第1章-SVN概述" class="headerlink" title="第1章 SVN概述"></a>第1章 SVN概述</h2><h3 id="SVN简介"><a href="#SVN简介" class="headerlink" title="SVN简介"></a>SVN简介</h3><h4 id="什么是SVN"><a href="#什么是SVN" class="headerlink" title="什么是SVN"></a>什么是SVN</h4><p>SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS迁移到Subversion。说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的。</p><h4 id="SVN的作用"><a href="#SVN的作用" class="headerlink" title="SVN的作用"></a>SVN的作用</h4><p>使用SVN的目的主要有两个:</p><blockquote><p>实现项目组中的资源共享<br>实现资源文件的版本控制</p></blockquote><h4 id="SVN的工作原理"><a href="#SVN的工作原理" class="headerlink" title="SVN的工作原理"></a>SVN的工作原理</h4><p>Subversion是一个自由开源的版本控制系统。在Subversion管理下,文件和目录可以超越时空。Subversion将文件存放在中心版本库里,这个版本库很像一个普通的文件服务器,不同的是,它可以记录每一次文件和目录的修改情况,这样就可以借此将数据恢复到以前的版本,并可以查看数据的更改细节。正因为如此,许多人将版本控制系统当作一种神奇的“时间机器”。<br><img src="/images/version/svn/svn02.png" alt="效果图"></p><h3 id="传统文件共享方式的弊端"><a href="#传统文件共享方式的弊端" class="headerlink" title="传统文件共享方式的弊端"></a>传统文件共享方式的弊端</h3><h4 id="拷贝方式的弊端"><a href="#拷贝方式的弊端" class="headerlink" title="拷贝方式的弊端"></a>拷贝方式的弊端</h4><p><img src="/images/version/svn/svn03.png" alt="效果图"></p><blockquote><p>发送与接受文件的工作量巨大<br>无法及时获取到更新<br>对于之前版本的恢复较难,即使可以恢复,也大量浪费控件。<br>若一个文件由多个修改,则会出现内容冲突问题。且难于确定修改的具体时间及修改人。<br>······</p></blockquote><h4 id="文件服务器的弊端"><a href="#文件服务器的弊端" class="headerlink" title="文件服务器的弊端"></a>文件服务器的弊端</h4><p><img src="/images/version/svn/svn04.png" alt="效果图"></p><blockquote><p>空间大量浪费<br>资源无法设定访问权限<br>资源安全性很低<br>发生冲突资源,无法自动合并<br>·······</p></blockquote><h3 id="SVN的体系结构图"><a href="#SVN的体系结构图" class="headerlink" title="SVN的体系结构图"></a>SVN的体系结构图</h3><p><img src="/images/version/svn/svn05.jpg" alt="效果图"></p><h4 id="客户层"><a href="#客户层" class="headerlink" title="客户层"></a>客户层</h4><blockquote><p>GUI:图形化界面<br>Command Line:命令行</p></blockquote><h4 id="服务层"><a href="#服务层" class="headerlink" title="服务层"></a>服务层</h4><blockquote><p>http协议(需要Apache服务)<br>svn协议</p></blockquote><h4 id="仓库层"><a href="#仓库层" class="headerlink" title="仓库层"></a>仓库层</h4><blockquote><p>FSFS(常用)<br>Berkley DB(Oracle)</p></blockquote><h3 id="SVN的下载"><a href="#SVN的下载" class="headerlink" title="SVN的下载"></a>SVN的下载</h3><p><img src="/images/version/svn/svn06.png" alt="效果图"><br>下载页面链接:<a href="https://www.visualsvn.com/downloads/" target="_blank" rel="noopener">https://www.visualsvn.com/downloads/</a><br>Apache-Subversion下载地址: <a href="https://www.visualsvn.com/files/Apache-Subversion-1.10.0.zip" target="_blank" rel="noopener">Apache-Subversion-1.10.0.zip</a>.<br>VisualSVN-Server下载地址: <a href="https://www.visualsvn.com/files/VisualSVN-Server-3.8.1-x64.msi" target="_blank" rel="noopener">VisualSVN-Server-3.8.1-x64.msi</a>.</p><h2 id="第2章-SVN命令行的使用"><a href="#第2章-SVN命令行的使用" class="headerlink" title="第2章 SVN命令行的使用"></a>第2章 SVN命令行的使用</h2><h3 id="SVN的安装与配置"><a href="#SVN的安装与配置" class="headerlink" title="SVN的安装与配置"></a>SVN的安装与配置</h3><h4 id="SVN安装"><a href="#SVN安装" class="headerlink" title="SVN安装"></a>SVN安装</h4><p>下载Apache-Subversion,并解压到D盘Subversion目录下,通过命令行提示符(管理员)及CMD命令,进入D盘下Subversion\bin目录,输入svn -h,如果出现如下图一串,说明SVN没有问题。<br><img src="/images/version/svn/svn07.png" alt="效果图"><br><img src="/images/version/svn/svn08.png" alt="效果图"></p><h4 id="SVN环境变量配置"><a href="#SVN环境变量配置" class="headerlink" title="SVN环境变量配置:"></a>SVN环境变量配置:</h4><p>SVN_HOME:D:\Subversion<br>Path:%SVN_HOME%\bin</p><h3 id="SVN常用命令"><a href="#SVN常用命令" class="headerlink" title="SVN常用命令"></a>SVN常用命令</h3><h4 id="SVN管理员命令"><a href="#SVN管理员命令" class="headerlink" title="SVN管理员命令"></a>SVN管理员命令</h4><h5 id="svnadmin-help"><a href="#svnadmin-help" class="headerlink" title="svnadmin help"></a>svnadmin help</h5><p>查看所有管理员命令:svnadmin help<br><img src="/images/version/svn/svn09.png" alt="效果图"></p><h5 id="svnadmin-–version"><a href="#svnadmin-–version" class="headerlink" title="svnadmin –version"></a>svnadmin –version</h5><p>查看当前svn版本:svnadmin –version<br><img src="/images/version/svn/svn10.png" alt="效果图"></p><h5 id="svnadmin-help-create"><a href="#svnadmin-help-create" class="headerlink" title="svnadmin help create"></a>svnadmin help create</h5><p>查看当前命令如何使用:svnadmin help create<br><img src="/images/version/svn/svn11.png" alt="效果图"></p><h5 id="svnadmin-create"><a href="#svnadmin-create" class="headerlink" title="svnadmin create"></a>svnadmin create</h5><p>创建SVN版本仓库:svnadmin create</p><blockquote><p>SVN仓库分为两级:顶级仓库与根仓库<br>该命令用于创建SVN版本仓库,确切说,创建的是根仓库。<br>注意,在创建根仓库时,顶层仓库目录必须是存在的,其不会自动创建。根仓库目录是否存在,均是可以的。若根仓库目录不存在,命令会自动创建该根仓库。<br><img src="/images/version/svn/svn12.png" alt="效果图"></p></blockquote><h5 id="svn仓库目录结构"><a href="#svn仓库目录结构" class="headerlink" title="svn仓库目录结构"></a>svn仓库目录结构</h5><p>svn仓库目录如下:</p><blockquote><p>conf:配置文件(svnserver.conf:连接仓库,authz:权限, passwd:密码, &gt;hooks-env.tmpl:钩子运行环境配置,可以实现客户端数据的自动更新功能)<br>db: 具体版本内容(不存在冗余,以日志方式保存)<br>hooks: 可以实现客户端数据的自动更新功能<br>locks: 锁<br><img src="/images/version/svn/svn13.png" alt="效果图"></p></blockquote><h4 id="SVN服务端命令"><a href="#SVN服务端命令" class="headerlink" title="SVN服务端命令"></a>SVN服务端命令</h4><h5 id="svnserve-d"><a href="#svnserve-d" class="headerlink" title="svnserve -d"></a>svnserve -d</h5><p><img src="/images/version/svn/svn14.png" alt="效果图"></p><blockquote><p>svnserve -d 用于开启DOS系统下的SVN服务<br><img src="/images/version/svn/svn15.png" alt="效果图"><br>此守护线程监控着一个端口,即svn服务默认端口3690<br>netstat -a 命令查看当前网络的连接状态。net status<br><img src="/images/version/svn/svn16.png" alt="效果图"></p></blockquote><h5 id="svnserve-d-–listen-port-8888"><a href="#svnserve-d-–listen-port-8888" class="headerlink" title="svnserve -d –listen-port=8888"></a>svnserve -d –listen-port=8888</h5><blockquote><p><img src="/images/version/svn/svn17.png" alt="效果图"><br><img src="/images/version/svn/svn18.png" alt="效果图"><br>可以看出,监听端口没有3690,而是8888<br>svn://localhost:3690/ G:/ENML/SVNRepositories/test 等价于svn://localhost/ G:/ENML/SVNRepositories/test<br>svnserve -d –listen-port=8888 指定SVN服务占用的端口号为8888<br>svn://localhost:8888/ G:/ENML/SVNRepositories/test</p></blockquote><h5 id="svnserve-d-r"><a href="#svnserve-d-r" class="headerlink" title="svnserve -d -r"></a>svnserve -d -r</h5><blockquote><p>可以看到 G:/ENML/SVNRepositories/test这层目录暴露出来存在极大的安全隐患,但是顶层仓库是必须要告诉给客户端的<br>我们可以用另外一个参数指定顶层仓库的位置,这样以后顶层仓库就不用再写了。<br><img src="/images/version/svn/svn19.png" alt="效果图"><br>svnserve -d -r G:/ENML/SVNRepositories 指定默认的SVN顶层仓库的路径。一旦指定,那么客户端在使用svn时直接跟仓库名即可。<br>svn://localhost/test</p></blockquote><h5 id="将SVN服务注册为开机自启动的windows服务"><a href="#将SVN服务注册为开机自启动的windows服务" class="headerlink" title="将SVN服务注册为开机自启动的windows服务"></a>将SVN服务注册为开机自启动的windows服务</h5><blockquote><p>sc create SVNService binpath=”D:/Subversion/bin/svnserve.exe –service -r G:/ENML/SVNRepositories” start=auto depend=Tcpip<br>启动SVN服务: net start SVNService<br>停止SVN服务: net stop SVNService<br>删除SVN服务: sc delete SVNService(删除之前最好先停止系统服务)<br>注意:该命令需要在具有管理员权限的窗口运行,win7、win8情况下”binpath=”后面需要跟一个空格。<br><img src="/images/version/svn/svn21.png" alt="效果图"><br><img src="/images/version/svn/svn22.png" alt="效果图"><br><img src="/images/version/svn/svn23.png" alt="删除效果图"><br></p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">sc:<span class="built_in"> server </span>create</span><br><span class="line">binpath:二进制程序执行命令及路径</span><br><span class="line">--service: Windows<span class="built_in"> service </span>mode (Service Control Manager)</span><br><span class="line">-r: 顶级仓库目录</span><br><span class="line">start: 启动模式,auto自启动</span><br></pre></td></tr></table></figure><p></p></blockquote><h4 id="SVN客户端命令"><a href="#SVN客户端命令" class="headerlink" title="SVN客户端命令"></a>SVN客户端命令</h4><h5 id="svn-checkout"><a href="#svn-checkout" class="headerlink" title="svn checkout"></a>svn checkout</h5><p>checkout,称为检出。其意义为:创建客户端指定目录与服务端指定仓库间的连接关系。客户端指定的这个目录,官方名称working copy,通常称为客户端连接目录。<br>一个客户端一般情况下,只需要检出一次。<br>A. 基于顶层仓库的checkout<br><img src="/images/version/svn/svn24.png" alt="效果图"><br>在任意目录下运行此命令:<br>svn checkout svn://localhost/sms d:/course/svn/group/aacof<br>其运行效果为,在aacof目录中出现一个.svn隐藏目录。<br><img src="/images/version/svn/svn25.png" alt="效果图"><br>svn checkout svn://localhost/sms<br>若当前执行命令的目录为Working Copy目录,则运行以下命令后的结果为:<br><img src="/images/version/svn/svn26.png" alt="效果图"><br>在working copy中会出现根仓库目录,而根仓库目录中会存在.svn隐藏目录。<br>B. 基于根仓库的checkout<br>基于根仓库的服务创建<br><img src="/images/version/svn/svn27.png" alt="效果图"><br>无论是在任意目录运行checkout,还是在working copy中运行checkout,其运行效果是相同的,都是在working copy目录中产生一个.svn的隐藏目录。<br><img src="/images/version/svn/svn28.png" alt="效果图"><br><img src="/images/version/svn/svn29.png" alt="效果图"></p><h5 id="服务端修改客户端权限"><a href="#服务端修改客户端权限" class="headerlink" title="服务端修改客户端权限"></a>服务端修改客户端权限</h5><p><img src="/images/version/svn/svn30.png" alt="效果图"></p><h5 id="svn-add"><a href="#svn-add" class="headerlink" title="svn add"></a>svn add</h5><p>A. add 文件<br>当一个文件/目录,被存放到working copy中时,SVN并不会感知到它的存在,即SVN并不会对其进行管理。若要SVN对其进行管理,必须将其通知add命令,添加到SVN管理中。需要注意,<br>(1) 被add的文件/目录,必须存在于woring copy中。<br>(2) add命令的作用就是将制定文件/目录交由SVN进行管理,所以一个文件/目录一般情况下,就执行一次add命令即可。add命令的执行与文件是否被修改过没有任何关系。<br>(3) 被add的目录,会将当前目录及其所包含的所有文件/目录,一次性<br><img src="/images/version/svn/svn31.png" alt="效果图"><br><img src="/images/version/svn/svn32.png" alt="效果图"><br>B. add 目录<br>add目录与add文件一样,即svn add 目录名</p><h5 id="svn-commit"><a href="#svn-commit" class="headerlink" title="svn commit"></a>svn commit</h5><p>commit命令用于将客户端working copy中所有对文件/目录的操作提交到服务端。<br><img src="/images/version/svn/svn33.png" alt="效果图"></p><h2 id="第3章-TortoiseSVN客户端"><a href="#第3章-TortoiseSVN客户端" class="headerlink" title="第3章 TortoiseSVN客户端"></a>第3章 TortoiseSVN客户端</h2><h2 id="第4章-Eclipse-SVN客户端"><a href="#第4章-Eclipse-SVN客户端" class="headerlink" title="第4章 Eclipse SVN客户端"></a>第4章 Eclipse SVN客户端</h2><h2 id="第5章-SVN与Apache服务整合"><a href="#第5章-SVN与Apache服务整合" class="headerlink" title="第5章 SVN与Apache服务整合"></a>第5章 SVN与Apache服务整合</h2><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;第1章-SVN概述&quot;&gt;&lt;a href=&quot;#第1章-SVN概述&quot; class=&quot;headerlink&quot; title=&quot;第1章 SVN概述
</summary>
<category term="SVN" scheme="http://smartdot.club/categories/SVN/"/>
<category term="SVN" scheme="http://smartdot.club/tags/SVN/"/>
</entry>
<entry>
<title>svn备份还原</title>
<link href="http://smartdot.club/%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6/SVN/svn%E5%A4%87%E4%BB%BD%E8%BF%98%E5%8E%9F/"/>
<id>http://smartdot.club/版本控制/SVN/svn备份还原/</id>
<published>2018-04-10T00:51:01.000Z</published>
<updated>2019-02-27T08:43:24.234Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><p>备份:svnadmin dump D:\Repositories\TestProject &gt; D:\svndumpfile\TestProject_20090722.dump<br>还原:<br>1、将dump文件拷贝到目标机器</p><p>2、在目标机器创建仓库:</p><p>svnadmin create D:/repositories/TestProject</p><p>并注意检查是否需要修改文件夹权限</p><p>3、执行命令svnadmin load:</p><p>svnadmin load D:/repositories/TestProject &lt; D:/TestProject_20090722.dump</p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;p&gt;备份:svnadmin dump D:\Repositories\TestProject &amp;gt; D:\svndumpfile\TestPro
</summary>
<category term="SVN" scheme="http://smartdot.club/categories/SVN/"/>
<category term="SVN" scheme="http://smartdot.club/tags/SVN/"/>
</entry>
<entry>
<title>java反射机制</title>
<link href="http://smartdot.club/Java/java%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6/"/>
<id>http://smartdot.club/Java/java反射机制/</id>
<published>2017-12-03T12:17:09.000Z</published>
<updated>2019-02-27T08:43:24.215Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h3 id="根据class获取java对象的三种方式"><a href="#根据class获取java对象的三种方式" class="headerlink" title="根据class获取java对象的三种方式"></a>根据class获取java对象的三种方式</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 第一种方式</span></span><br><span class="line">Class c1 = Class.forName(<span class="string">"com.caifenglin.reflect.Employee"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 第二种方式</span></span><br><span class="line"><span class="comment">// java中每个类型都class属性</span></span><br><span class="line">Class c2 = Employee.class;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 第三种方式</span></span><br><span class="line"><span class="comment">// java语言中任何一个java对象都有getClass方法</span></span><br><span class="line">Employee e = <span class="keyword">new</span> Employee();</span><br><span class="line"><span class="comment">// c3是运行时类(e的运行时类是Emplyoee)</span></span><br><span class="line">Class c3 = e.getClass();</span><br></pre></td></tr></table></figure><p>注意:在使用.class反射获取对象时不会执行对象中的静态代码块,如下:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflelctTest02</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> ClassNotFoundException </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 将A.class文件装载到JVM中的过程,会执行静态语句块</span></span><br><span class="line"><span class="comment">// Class.forName("com.caifenglin.reflect.A");</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 不会执行静态语句块</span></span><br><span class="line">Class c = com.caifenglin.reflect.A.class;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> </span>&#123;</span><br><span class="line"><span class="keyword">static</span> &#123;</span><br><span class="line">System.out.println(<span class="string">"A········"</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h3 id="获取Class类型的对象之后,可以创建该类的对象"><a href="#获取Class类型的对象之后,可以创建该类的对象" class="headerlink" title="获取Class类型的对象之后,可以创建该类的对象"></a>获取Class类型的对象之后,可以创建该类的对象</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectTest03</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">Class c = Class.forName(<span class="string">"com.caifenglin.reflect.Employee"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建此Class对象所表示的一个新实例,调用了Emplyoee的无参构造方法</span></span><br><span class="line">Object o = c.newInstance();</span><br><span class="line">System.out.println(o);</span><br><span class="line"><span class="comment">// com.caifenglin.reflect.Employee@7852e922</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Class c1 = Class.forName(<span class="string">"java.util.Date"</span>);</span><br><span class="line">Object o1 = c1.newInstance();</span><br><span class="line"><span class="keyword">if</span>(o1 <span class="keyword">instanceof</span> Date) &#123;</span><br><span class="line">Date d = (Date)o1;</span><br><span class="line">System.out.println(<span class="keyword">new</span> SimpleDateFormat(<span class="string">"yyyy年MM月dd日 HH时mm分ss秒"</span>).format(d));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>java.lang.reflect.Field; 类中的属性反编译所有类中的属性<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * java.lang.reflect.Field; 类中的属性</span></span><br><span class="line"><span class="comment"> * 反编译所有类中的属性</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> caifenglin</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectTest04</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取整个类</span></span><br><span class="line">Class c = Class.forName(<span class="string">"com.caifenglin.reflect.Student"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取属性Field</span></span><br><span class="line"><span class="comment">// 获取所有public修饰的属性</span></span><br><span class="line">Field[] fs = c.getFields();</span><br><span class="line"></span><br><span class="line">System.out.println(fs.length);</span><br><span class="line">System.out.println(fs[<span class="number">0</span>]);</span><br><span class="line">System.out.println(<span class="string">"======================="</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Field[] dfs = c.getDeclaredFields();</span><br><span class="line"><span class="comment">/*for (Field field : dfs) &#123;</span></span><br><span class="line"><span class="comment">int i = field.getModifiers();</span></span><br><span class="line"><span class="comment">String modifiers = Modifier.toString(i);</span></span><br><span class="line"><span class="comment">System.out.println(modifiers);</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Class type = field.getType();</span></span><br><span class="line"><span class="comment">//System.out.println("type名称"+type.getName());</span></span><br><span class="line"><span class="comment">System.out.println(type.getSimpleName());</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">System.out.println(field.getName());</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br><span class="line"></span><br><span class="line">StringBuffer sb = <span class="keyword">new</span> StringBuffer();</span><br><span class="line">sb.append(Modifier.toString(c.getModifiers()) + <span class="string">" class "</span> + c.getSimpleName() + <span class="string">"&#123;"</span>);</span><br><span class="line"><span class="keyword">for</span> (Field field : dfs) &#123;</span><br><span class="line">sb.append(<span class="string">"\t"</span>);</span><br><span class="line">sb.append(Modifier.toString(field.getModifiers()) + <span class="string">" "</span>);</span><br><span class="line">sb.append(field.getType().getSimpleName() + <span class="string">" "</span>);</span><br><span class="line">sb.append(field.getName() + <span class="string">";\n"</span>);</span><br><span class="line">&#125;</span><br><span class="line">sb.append(<span class="string">"&#125;"</span>);</span><br><span class="line">System.out.println(sb);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h3 id="java-lang-reflect-Filed-获取某个指定的属性"><a href="#java-lang-reflect-Filed-获取某个指定的属性" class="headerlink" title="java.lang.reflect.Filed; 获取某个指定的属性"></a>java.lang.reflect.Filed; 获取某个指定的属性</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectTest05</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line">Class c = Class.forName(<span class="string">"com.caifenglin.reflect.Student"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取所有属性</span></span><br><span class="line"><span class="comment">//Field[] fs = c.getDeclaredFields();</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取某个特定属性,获取name属性</span></span><br><span class="line">Field df = c.getDeclaredField(<span class="string">"name"</span>);</span><br><span class="line"></span><br><span class="line">Object o = c.newInstance();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 打破封装</span></span><br><span class="line">df.setAccessible(<span class="keyword">true</span>);<span class="comment">// 使用反射机制可以打破封装机制,使java对象的属性不安全</span></span><br><span class="line"></span><br><span class="line">df.set(o, <span class="string">"caifenglin"</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(df.get(o));</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="java-lang-reflect-Method-获取类中的方法反编译所有类中的方法"><a href="#java-lang-reflect-Method-获取类中的方法反编译所有类中的方法" class="headerlink" title="java.lang.reflect.Method;获取类中的方法反编译所有类中的方法"></a>java.lang.reflect.Method;获取类中的方法反编译所有类中的方法</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectMethod01</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"><span class="comment">// 获取类</span></span><br><span class="line"><span class="comment">//Class c = Class.forName("com.caifenglin.reflect.Student");</span></span><br><span class="line">Class c = Class.forName(<span class="string">"java.lang.String"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取所有方法</span></span><br><span class="line"><span class="comment">/*Method[] methods = c.getDeclaredMethods();</span></span><br><span class="line"><span class="comment">for (Method method : methods) &#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 修饰符</span></span><br><span class="line"><span class="comment">System.out.println(Modifier.toString(method.getModifiers()));</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 方法的返回值类型</span></span><br><span class="line"><span class="comment">Class returnType = method.getReturnType();</span></span><br><span class="line"><span class="comment">System.out.println(returnType.getSimpleName());</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 方法名</span></span><br><span class="line"><span class="comment">System.out.println(method.getName());</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 方法的形式参数</span></span><br><span class="line"><span class="comment">Class[] paramterTypes = method.getParameterTypes();</span></span><br><span class="line"><span class="comment">for (Class paramterType : paramterTypes) &#123;</span></span><br><span class="line"><span class="comment">System.out.println(paramterType.getSimpleName());</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 反编译</span></span><br><span class="line">StringBuffer sb = <span class="keyword">new</span> StringBuffer();</span><br><span class="line">sb.append(Modifier.toString(c.getModifiers()) + <span class="string">" class "</span>);</span><br><span class="line">sb.append(c.getSimpleName() + <span class="string">"&#123;\n"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取所有方法</span></span><br><span class="line">Method[] methods = c.getDeclaredMethods();</span><br><span class="line"><span class="keyword">for</span> (Method m : methods) &#123;</span><br><span class="line">sb.append(<span class="string">"\t"</span>);</span><br><span class="line">sb.append(Modifier.toString(m.getModifiers()) + <span class="string">" "</span>);</span><br><span class="line">sb.append(m.getReturnType().getSimpleName()+ <span class="string">" "</span>);</span><br><span class="line">sb.append(m.getName()+<span class="string">"("</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 形参</span></span><br><span class="line">Class[] parameterTypes = m.getParameterTypes();</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; parameterTypes.length; i++) &#123;</span><br><span class="line">Class parameterType = parameterTypes[i];</span><br><span class="line"><span class="keyword">if</span>(i == parameterTypes.length - <span class="number">1</span>) &#123;</span><br><span class="line">sb.append(parameterType.getSimpleName());</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">sb.append(parameterType.getSimpleName() + <span class="string">", "</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sb.append(<span class="string">")&#123;&#125;\n"</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">sb.append(<span class="string">"&#125;"</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(sb);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="获取某个特定的方法,通过反射机制执行"><a href="#获取某个特定的方法,通过反射机制执行" class="headerlink" title="获取某个特定的方法,通过反射机制执行"></a>获取某个特定的方法,通过反射机制执行</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取某个特定的方法,通过反射机制执行</span></span><br><span class="line"><span class="comment"> * 以前:Student student = new Student();</span></span><br><span class="line"><span class="comment"> * boolean isSuccess = student.login("admin","123");</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> caifenglin</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectMethod02</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"><span class="comment">// 1.获取类</span></span><br><span class="line">Class c = Class.forName(<span class="string">"com.caifenglin.reflect.Student"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取某个特定的方法</span></span><br><span class="line"><span class="comment">// 通过:方法名+形参列表</span></span><br><span class="line">Method m = c.getDeclaredMethod(<span class="string">"login"</span>, String.class, String.class);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过反射机制执行login方法</span></span><br><span class="line">Object o = c.newInstance();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用o对象的m方法,传递"admin", "123"参数,方法的执行结果是retValue</span></span><br><span class="line">Object retValue = m.invoke(o, <span class="string">"admin"</span>, <span class="string">"123"</span>);</span><br><span class="line">System.out.println(retValue);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="java-lang-reflect-Constructor-获取类中的构造方法反编译所有类中的所有构造方法"><a href="#java-lang-reflect-Constructor-获取类中的构造方法反编译所有类中的所有构造方法" class="headerlink" title="java.lang.reflect.Constructor;获取类中的构造方法反编译所有类中的所有构造方法"></a>java.lang.reflect.Constructor;获取类中的构造方法反编译所有类中的所有构造方法</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectConstruct01</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1.获取类</span></span><br><span class="line">Class c = Class.forName(<span class="string">"java.lang.String"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.获取所有的构造</span></span><br><span class="line">Constructor[] cs = c.getDeclaredConstructors();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">for (Constructor constructor : cs) &#123;</span></span><br><span class="line"><span class="comment">// 获取修饰符</span></span><br><span class="line"><span class="comment">System.out.println(Modifier.toString(constructor.getModifiers()));</span></span><br><span class="line"><span class="comment">// 获取构造方法名</span></span><br><span class="line"><span class="comment">System.out.println(c.getName());</span></span><br><span class="line"><span class="comment">// 构造方法的形式参数列表</span></span><br><span class="line"><span class="comment">Class[] parameterTypes = constructor.getParameterTypes();</span></span><br><span class="line"><span class="comment">for (Class parameterType : parameterTypes) &#123;</span></span><br><span class="line"><span class="comment">System.out.println(parameterType.getSimpleName());</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">&#125;*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 反编译</span></span><br><span class="line">StringBuffer sb = <span class="keyword">new</span> StringBuffer();</span><br><span class="line">sb.append(Modifier.toString(c.getModifiers()) + <span class="string">" class "</span> + c.getSimpleName() + <span class="string">"&#123;\n"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 构造方法</span></span><br><span class="line"><span class="keyword">for</span> (Constructor constructor : cs) &#123;</span><br><span class="line">sb.append(<span class="string">"\t"</span>);</span><br><span class="line">sb.append(Modifier.toString(constructor.getModifiers()) + <span class="string">" "</span>);</span><br><span class="line">sb.append(c.getSimpleName() + <span class="string">"("</span>);</span><br><span class="line"><span class="comment">// 形参</span></span><br><span class="line">Class[] parameterTypes = constructor.getParameterTypes();</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; parameterTypes.length; i++) &#123;</span><br><span class="line">Class parameterType = parameterTypes[i];</span><br><span class="line"><span class="keyword">if</span>(i == parameterTypes.length - <span class="number">1</span>) &#123;</span><br><span class="line">sb.append(parameterType.getSimpleName());</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">sb.append(parameterType.getSimpleName() + <span class="string">", "</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sb.append(<span class="string">")&#125;\n"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">sb.append(<span class="string">"&#125;"</span>);</span><br><span class="line">System.out.println(sb);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="java-lang-reflect-Constructor-获取某个特定的构造方法"><a href="#java-lang-reflect-Constructor-获取某个特定的构造方法" class="headerlink" title="java.lang.reflect.Constructor;获取某个特定的构造方法"></a>java.lang.reflect.Constructor;获取某个特定的构造方法</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectConstruct02</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1.获取类</span></span><br><span class="line">Class c = Class.forName(<span class="string">"com.caifenglin.reflect.Customer"</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.获取特定的构造方法</span></span><br><span class="line">Constructor dc = c.getDeclaredConstructor(String.class, <span class="keyword">int</span>.class);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3.创建对象</span></span><br><span class="line">Object o = dc.newInstance(<span class="string">"李四"</span>, <span class="number">24</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(o);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>以上反射中的实体类:<br>员工类<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.caifenglin.reflect;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Employee</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Field</span></span><br><span class="line"><span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Constructor</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">()</span> </span>&#123;</span><br><span class="line">System.out.println(<span class="string">"Employee无参构造方法执行"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">Employee</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line"><span class="keyword">this</span>.name = name;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// method</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">work</span><span class="params">()</span> </span>&#123;</span><br><span class="line">System.out.print(<span class="string">"在工作!"</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>student类<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Student</span> </span>&#123;</span><br><span class="line"><span class="comment">// Field</span></span><br><span class="line"><span class="keyword">private</span> String name;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span> age;</span><br><span class="line"><span class="keyword">protected</span> String address;</span><br><span class="line"><span class="keyword">boolean</span> sex;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">login</span><span class="params">(String username, String password)</span> </span>&#123;</span><br><span class="line"><span class="keyword">if</span>(<span class="string">"admin"</span>.equals(username) &amp;&amp; <span class="string">"123"</span>.equals(password)) &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">m1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">System.out.println(<span class="string">"hello reflect"</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>可变长参数举例<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 关于Java中的可变长参数</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> caifenglin</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test01</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 可变长参数只能出现一次,并且只能出现在最后的位置</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">m1</span><span class="params">(<span class="keyword">int</span>... a)</span> </span>&#123;</span><br><span class="line">System.out.println(<span class="string">"Test"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">m1</span><span class="params">(<span class="keyword">int</span> a)</span> </span>&#123;</span><br><span class="line">System.out.println(<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果有精确匹配的方法,则调用该精确方法;可变参数可以看做数组</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">m1();</span><br><span class="line">m1(<span class="number">2</span>);</span><br><span class="line">m1(<span class="number">1</span>,<span class="number">2</span>);</span><br><span class="line">m1(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h3 id=&quot;根据class获取java对象的三种方式&quot;&gt;&lt;a href=&quot;#根据class获取java对象的三种方式&quot; class=&quot;header
</summary>
<category term="Java" scheme="http://smartdot.club/categories/Java/"/>
<category term="Java" scheme="http://smartdot.club/tags/Java/"/>
</entry>
<entry>
<title>适配器模式</title>
<link href="http://smartdot.club/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F/"/>
<id>http://smartdot.club/设计模式/适配器模式/</id>
<published>2017-12-03T12:17:09.000Z</published>
<updated>2019-02-27T08:43:24.241Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --><h2 id="适配器模式"><a href="#适配器模式" class="headerlink" title="适配器模式"></a>适配器模式</h2><h3 id="适配器模式概念"><a href="#适配器模式概念" class="headerlink" title="适配器模式概念"></a>适配器模式概念</h3><p>适配器模式的定义是,Convert the interface of a class into another interface clients<br>expect,将某个类的接口转换为客户所需的类型。换句话说,适配器模式解决的问题是,使得原本由于接口不兼容而不<br>能一起工作、不能统一管理的那些类可以在一起工作、可以进行统一管理。</p><p>这样解释适配器的概念还是很抽象。下面以不同工种的工作内容不同,实现统一管理为例来解释适配器设计模式。</p><h3 id="未使用适配器模式举例"><a href="#未使用适配器模式举例" class="headerlink" title="未使用适配器模式举例"></a>未使用适配器模式举例</h3><p>厨师接口,厨师的任务是烹饪<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>厨师的实现类,全聚德的厨师<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QjdCooker</span> <span class="keyword">implements</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"烤制美味烤鸭"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员接口,程序员的任务是编程<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"><span class="function">String <span class="title">programmer</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员的实现类,京东程序员<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdProgrammer</span> <span class="keyword">implements</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">programmer</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"编写高效程序"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>测试类:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.JdProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.QjdCooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 未使用适配器</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">ICooker qjdCooker = <span class="keyword">new</span> QjdCooker();</span><br><span class="line">IProgrammer jdProgrammer = <span class="keyword">new</span> JdProgrammer();</span><br><span class="line">System.out.println(qjdCooker.cook());</span><br><span class="line">System.out.println(jdProgrammer.programmer());</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h3 id="使用适配器模式举例"><a href="#使用适配器模式举例" class="headerlink" title="使用适配器模式举例"></a>使用适配器模式举例</h3><p>厨师接口,厨师的任务是烹饪<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>厨师的实现类,全聚德的厨师<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QjdCooker</span> <span class="keyword">implements</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"烤制美味烤鸭"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员接口,程序员的任务是编程<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"><span class="function">String <span class="title">programmer</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员的实现类,京东程序员<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdProgrammer</span> <span class="keyword">implements</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">programmer</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"编写高效程序"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>适配器接口:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.adapters;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IWorkerAdapter</span> </span>&#123;</span><br><span class="line"><span class="function">String <span class="title">work</span><span class="params">(Object work)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>适配器实现类:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.adapters.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.IWorkerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"><span class="comment">//适配器类</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WorkerAdapterImpl</span> <span class="keyword">implements</span> <span class="title">IWorkerAdapter</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">work</span><span class="params">(Object work)</span> </span>&#123;</span><br><span class="line">String workContent = <span class="string">""</span>;</span><br><span class="line"><span class="comment">//若传来的对象是厨师,则调用其cook()方法</span></span><br><span class="line"><span class="keyword">if</span>(work <span class="keyword">instanceof</span> ICooker) &#123;</span><br><span class="line">workContent = ((ICooker)work).cook();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(work <span class="keyword">instanceof</span> IProgrammer) &#123;</span><br><span class="line">workContent = ((IProgrammer)work).programmer();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> workContent;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>测试类:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.IWorkerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.impl.WorkerAdapterImpl;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.JdProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.QjdCooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 使用适配器</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">ICooker qjdCooker = <span class="keyword">new</span> QjdCooker();</span><br><span class="line">IProgrammer jdProgrammer = <span class="keyword">new</span> JdProgrammer();</span><br><span class="line">Object[] works = &#123;qjdCooker, jdProgrammer&#125;;</span><br><span class="line">IWorkerAdapter adapter = <span class="keyword">new</span> WorkerAdapterImpl();</span><br><span class="line"><span class="comment">//循环遍历每个工种对象,让每个工种对象在适配器中逐个进行匹配</span></span><br><span class="line"><span class="keyword">for</span> (Object worker : works) &#123;</span><br><span class="line">String workContent = adapter.work(worker);</span><br><span class="line">System.out.println(workContent);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><h3 id="适配器模式最终版"><a href="#适配器模式最终版" class="headerlink" title="适配器模式最终版"></a>适配器模式最终版</h3><p>厨师接口,厨师的任务是烹饪<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>厨师的实现类,全聚德的厨师<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QjdCooker</span> <span class="keyword">implements</span> <span class="title">ICooker</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">cook</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"烤制美味烤鸭"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员接口,程序员的任务是编程<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"><span class="function">String <span class="title">programmer</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>程序员的实现类,京东程序员<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.worker.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdProgrammer</span> <span class="keyword">implements</span> <span class="title">IProgrammer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">programmer</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> <span class="string">"编写高效程序"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>适配器接口类:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.adapters;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">IWorkerAdapter</span> </span>&#123;</span><br><span class="line"><span class="function">String <span class="title">work</span><span class="params">(Object worker)</span></span>;</span><br><span class="line"><span class="function">Boolean <span class="title">supports</span><span class="params">(Object worker)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>适配器实现类CookerAdapter.java<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.adapters.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.IWorkerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CookerAdapter</span> <span class="keyword">implements</span> <span class="title">IWorkerAdapter</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">work</span><span class="params">(Object worker)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> ((ICooker)worker).cook();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Boolean <span class="title">supports</span><span class="params">(Object worker)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> (worker <span class="keyword">instanceof</span> ICooker);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>适配器实现类ProgrammerAdapter.java<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.adapters.impl;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.IWorkerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProgrammerAdapter</span> <span class="keyword">implements</span> <span class="title">IWorkerAdapter</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">work</span><span class="params">(Object worker)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> ((IProgrammer)worker).programmer();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Boolean <span class="title">supports</span><span class="params">(Object worker)</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> (worker <span class="keyword">instanceof</span> IProgrammer);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><p>测试类:<br></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.learn.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.IWorkerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.impl.CookerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.adapters.impl.ProgrammerAdapter;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.ICooker;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.IProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.JdProgrammer;</span><br><span class="line"><span class="keyword">import</span> com.learn.worker.impl.QjdCooker;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyTest</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 使用适配器</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">ICooker qjdCooker = <span class="keyword">new</span> QjdCooker();</span><br><span class="line">IProgrammer jdProgrammer = <span class="keyword">new</span> JdProgrammer();</span><br><span class="line">Object[] works = &#123;qjdCooker, jdProgrammer&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//循环遍历每个工种对象,让每个工种对象在适配器中逐个进行匹配</span></span><br><span class="line"><span class="keyword">for</span> (Object worker : works) &#123;</span><br><span class="line">IWorkerAdapter adapter = getAdapter(worker);</span><br><span class="line">System.out.println(adapter.work(worker));</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Title</span>: getAdapter </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 根据worker获取相应的适配器模式</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <span class="doctag">@param</span> worker</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 返回类型为:IWorkerAdapter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">static</span> IWorkerAdapter <span class="title">getAdapter</span><span class="params">(Object worker)</span> </span>&#123;</span><br><span class="line">List&lt;IWorkerAdapter&gt; adapters = getAllAdapters();</span><br><span class="line"><span class="keyword">for</span> (IWorkerAdapter adapter : adapters) &#123;</span><br><span class="line"><span class="keyword">if</span>(adapter.supports(worker)) &#123;</span><br><span class="line"><span class="keyword">return</span> adapter;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Title</span>: getAllAdapters </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 获取所有的适配器</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 返回类型为:List&lt;IWorkerAdapter&gt;</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">static</span> List&lt;IWorkerAdapter&gt; <span class="title">getAllAdapters</span><span class="params">()</span> </span>&#123;</span><br><span class="line">List&lt;IWorkerAdapter&gt; adapters = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">adapters.add(<span class="keyword">new</span> CookerAdapter());</span><br><span class="line">adapters.add(<span class="keyword">new</span> ProgrammerAdapter());</span><br><span class="line"><span class="keyword">return</span> adapters;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:08 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;适配器模式&quot;&gt;&lt;a href=&quot;#适配器模式&quot; class=&quot;headerlink&quot; title=&quot;适配器模式&quot;&gt;&lt;/a&gt;适配器模式&lt;
</summary>
<category term="设计模式" scheme="http://smartdot.club/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="设计模式" scheme="http://smartdot.club/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
</entry>
<entry>
<title>openwrt路由器搭建svn服务器</title>
<link href="http://smartdot.club/%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6/SVN/openwrt%E8%B7%AF%E7%94%B1%E5%99%A8%E5%AE%89%E8%A3%85svn/"/>
<id>http://smartdot.club/版本控制/SVN/openwrt路由器安装svn/</id>
<published>2017-12-03T12:17:09.000Z</published>
<updated>2019-02-27T08:43:24.233Z</updated>
<content type="html"><![CDATA[<!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --><h2 id="GL-MT300A-OpenWrt路由器安装svn服务"><a href="#GL-MT300A-OpenWrt路由器安装svn服务" class="headerlink" title="GL-MT300A OpenWrt路由器安装svn服务"></a>GL-MT300A OpenWrt路由器安装svn服务</h2><p>入手一款Gl-MT300A便携式迷你路由器,基于openWrt系统,想在上面搭建一个svn,测试方便以后添加硬盘或者内存卡使用,将搭建步骤记录如下,我将其分为以下七步:</p><p>1 . 使用SecureCrt连接到路由器。</p><p>2 . 安装subversion-server<br></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">opkg update </span><br><span class="line">opkg install subversion-server</span><br></pre></td></tr></table></figure><p></p><p>3 . 安装完毕,使用svnserve –version查看版本,判断是否安装成功,然后创建第一个repository<br></p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p <span class="regexp">/mnt/</span>SVNRepositories<span class="regexp">/test/</span></span><br><span class="line">svnadmin create <span class="regexp">/mnt/</span>SVNRepositories<span class="regexp">/test/</span></span><br></pre></td></tr></table></figure><p></p><p>4 . 修改配置文件</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">vim /mnt/SVNRepositories/test/conf/svnserve.conf</span><br><span class="line">内容修改为如下:</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## This file controls the configuration of the svnserve daemon, if you</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## use it to allow access to this repository. (If you only allow</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## access through http: and/or file: URLs, then this file is</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## irrelevant.)</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## Visit http://subversion.apache.org/ for more information.</span></span></span><br><span class="line"></span><br><span class="line">[general]</span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## These options control access to the repository for unauthenticated</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## and authenticated users. Valid values are "write", "read",</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## and "none". The sample settings below are the defaults.</span></span></span><br><span class="line">anon-access = read</span><br><span class="line">auth-access = write</span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## The password-db option controls the location of the password</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## database file. Unless you specify a path starting with a /,</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## the file's location is relative to the directory containing</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## this configuration file.</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## If SASL is enabled (see below), this file will NOT be used.</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## Uncomment the line below to use the default password file.</span></span></span><br><span class="line">password-db = passwd</span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## The authz-db option controls the location of the authorization</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## rules for path-based access control. Unless you specify a path</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"><span class="comment">## starting with a /, the file's location is relative to the the</span></span></span><br></pre></td></tr></table></figure><figure class="highlight vala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">修改authz为如下:</span><br><span class="line"></span><br><span class="line">[aliases] </span><br><span class="line"><span class="meta"># joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average</span></span><br><span class="line"> </span><br><span class="line">[groups] </span><br><span class="line"><span class="meta"># harry_and_sally = harry,sally </span></span><br><span class="line"><span class="meta"># harry_sally_and_joe = harry,sally,&amp;joe </span></span><br><span class="line"><span class="meta"># [/foo/bar] </span></span><br><span class="line"><span class="meta"># harry = rw </span></span><br><span class="line"><span class="meta"># &amp;joe = r </span></span><br><span class="line"><span class="meta"># * = </span></span><br><span class="line"> </span><br><span class="line">[/] </span><br><span class="line"><span class="meta">### user config </span></span><br><span class="line">test = rw </span><br><span class="line">caifl = rw </span><br><span class="line"><span class="meta"># [repository:/baz/fuz] </span></span><br><span class="line"><span class="meta"># @harry_and_sally = rw </span></span><br><span class="line"><span class="meta"># * = r</span></span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">修改passwd如下:</span><br><span class="line"></span><br><span class="line">### This file is an example password file for svnserve.</span><br><span class="line">### Its format is similar to that of svnserve.conf. As shown in the</span><br><span class="line">### example below it contains one section labelled [users].</span><br><span class="line">### The name and password for each user follow, one account per line.</span><br><span class="line"></span><br><span class="line">[users]</span><br><span class="line"># harry = harryssecret</span><br><span class="line"># sally = sallyssecret</span><br><span class="line">### user password config</span><br><span class="line">test = test</span><br><span class="line">caifl = 19931129cfl</span><br></pre></td></tr></table></figure><p>5 . 进入目录/etc/config目录,修改文件subversion,配置本地仓库地址:vim /etc/confi/subversion</p><figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">配置如下:</span><br><span class="line">root@GL-MT300A:/etc/config# vim subversion </span><br><span class="line"></span><br><span class="line">config subversion</span><br><span class="line">### 本地仓库地址配置</span><br><span class="line"> option path <span class="string">'/mnt/SVNRepositories/'</span> </span><br><span class="line"> option port <span class="string">'3690'</span></span><br></pre></td></tr></table></figure><p>6 . 启动或者停止svn服务:<br></p><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">启动<span class="symbol">:/etc/init</span>.d/subversion start</span><br><span class="line">停止<span class="symbol">:/etc/init</span>.d/subversion stop</span><br></pre></td></tr></table></figure><p></p><p>7 . 通过TortoisSVN检出,路径地址:svn://192.168.0.1/test,输入配置的用户名和密码,即test检出成功。教程至此结束,特此谨记。<br><img src="/images/version/svn/svn01.png" alt="检出效果图"></p><!-- rebuild by neat -->]]></content>
<summary type="html">
&lt;!-- build time:Wed Mar 13 2019 22:44:09 GMT+0800 (GMT+08:00) --&gt;&lt;h2 id=&quot;GL-MT300A-OpenWrt路由器安装svn服务&quot;&gt;&lt;a href=&quot;#GL-MT300A-OpenWrt路由器安装svn服务&quot;
</summary>
<category term="SVN" scheme="http://smartdot.club/categories/SVN/"/>
<category term="SVN" scheme="http://smartdot.club/tags/SVN/"/>
</entry>
</feed>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mirroro/caifenglin.git
git@gitee.com:mirroro/caifenglin.git
mirroro
caifenglin
caifenglin
master

搜索帮助