<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>宋浩志的博客</title>
  
  
  <link href="https://www.songhaozhi.com/atom.xml" rel="self"/>
  
  <link href="https://www.songhaozhi.com/"/>
  <updated>2022-11-14T07:57:13.752Z</updated>
  <id>https://www.songhaozhi.com/</id>
  
  <author>
    <name>宋浩志</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Windows安装nacos</title>
    <link href="https://www.songhaozhi.com/2022/11/14/Windows%E5%AE%89%E8%A3%85nacos/"/>
    <id>https://www.songhaozhi.com/2022/11/14/Windows%E5%AE%89%E8%A3%85nacos/</id>
    <published>2022-11-14T07:06:46.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="下载安装包"><a href="#下载安装包" class="headerlink" title="下载安装包"></a>下载安装包</h2><p><a href="https://github.com/alibaba/nacos/releases">https://github.com/alibaba/nacos/releases</a></p><p>访问GitHub下载当前最新的安装包，解压到安装目录</p><h2 id="单机模式支持MySQL"><a href="#单机模式支持MySQL" class="headerlink" title="单机模式支持MySQL"></a>单机模式支持MySQL</h2><ul><li>1.安装数据库，版本要求：5.6.5+</li><li>2.初始化mysql数据库，数据库初始化文件：mysql-schema.sql</li><li>3.修改nacos&#x2F;conf&#x2F;application.properties文件，增加支持mysql数据源配置（目前只支持mysql），添加mysql数据源的url、用户名和密码。</li></ul><h2 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h2><p>Nacos启动需要准备64 bit JDK 1.8+环境。</p><p>启动命令(standalone代表着单机模式运行，非集群模式):</p><p><code>startup.cmd -m standalone</code> </p><p>Nacos默认是集群模式，也可以修改配置改为单机模式启动。</p><p>路径: <code>nacos/bin/startup.cmd</code></p><p><img src="/2022/11/14/Windows%E5%AE%89%E8%A3%85nacos/2022-11-14-15-14-07.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;下载安装包&quot;&gt;&lt;a href=&quot;#下载安装包&quot; class=&quot;headerlink&quot; title=&quot;下载安装包&quot;&gt;&lt;/a&gt;下载安装包&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/alibaba/nacos/releases&quot;&gt;https:</summary>
      
    
    
    
    <category term="Nacos" scheme="https://www.songhaozhi.com/categories/Nacos/"/>
    
    
    <category term="Nacos" scheme="https://www.songhaozhi.com/tags/Nacos/"/>
    
  </entry>
  
  <entry>
    <title>Edge用户登录一直转圈</title>
    <link href="https://www.songhaozhi.com/2022/11/14/Edge%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E4%B8%80%E7%9B%B4%E8%BD%AC%E5%9C%88/"/>
    <id>https://www.songhaozhi.com/2022/11/14/Edge%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E4%B8%80%E7%9B%B4%E8%BD%AC%E5%9C%88/</id>
    <published>2022-11-14T03:45:53.000Z</published>
    <updated>2022-11-14T07:57:13.740Z</updated>
    
    <content type="html"><![CDATA[<p>最近在Edge浏览器右上角登录微软账号的时候，提示0x80190001无法登录。</p><p>通过百度查到如下解决办法：</p><p>1.在控制面板或者IE浏览器中打开Internet选项，删除Cookie信息。</p><p>2.在Internet选项-“高级”菜单中，点击重置，重置网络设置。</p><p>操作以后不提示0x80190001错误信息了，但是一直在转圈，还是没办法登录。</p><p>最后通过设置成微软的DNS解决了</p><p><img src="/2022/11/14/Edge%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E4%B8%80%E7%9B%B4%E8%BD%AC%E5%9C%88/2022-11-14-11-51-04.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;最近在Edge浏览器右上角登录微软账号的时候，提示0x80190001无法登录。&lt;/p&gt;
&lt;p&gt;通过百度查到如下解决办法：&lt;/p&gt;
&lt;p&gt;1.在控制面板或者IE浏览器中打开Internet选项，删除Cookie信息。&lt;/p&gt;
&lt;p&gt;2.在Internet选项-“高级”菜单中</summary>
      
    
    
    
    <category term="Edge" scheme="https://www.songhaozhi.com/categories/Edge/"/>
    
    
    <category term="Edge" scheme="https://www.songhaozhi.com/tags/Edge/"/>
    
  </entry>
  
  <entry>
    <title>SpringBoot整合Socket</title>
    <link href="https://www.songhaozhi.com/2022/10/27/SpringBoot%E6%95%B4%E5%90%88Socket/"/>
    <id>https://www.songhaozhi.com/2022/10/27/SpringBoot%E6%95%B4%E5%90%88Socket/</id>
    <published>2022-10-27T09:57:01.000Z</published>
    <updated>2022-11-14T07:57:13.740Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>前段时间公司一个物联网项目需要通过TCP连接设备收发消息，现在我把代码整理出来，分享一下。</p><p>源代码已发布在<a href="https://github.com/gujiniCY/socket_demo">GitHub</a></p><h2 id="创建Socket"><a href="#创建Socket" class="headerlink" title="创建Socket"></a>创建Socket</h2><p>使用<code>ServerSocket</code>绑定<code>IP</code>和端口，</p><p><code>TcpSocket</code>实现Java的<code>Runnable</code>的类，在<code>run</code>方法中使用<code>Accept</code>监听端口是否有客户端发送连接请求，如果有连接来了就创建<code>SocketReceive</code>对象然后将他扔给线程池执行。</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></pre></td><td class="code"><pre><code class="hljs Java"><span class="hljs-keyword">package</span> com.example.socket_demo.socket;<br><br><span class="hljs-keyword">import</span> lombok.extern.slf4j.Slf4j;<br><span class="hljs-keyword">import</span> org.springframework.stereotype.Component;<br><br><span class="hljs-keyword">import</span> java.io.IOException;<br><span class="hljs-keyword">import</span> java.net.ServerSocket;<br><span class="hljs-keyword">import</span> java.net.Socket;<br><span class="hljs-keyword">import</span> java.util.concurrent.ExecutorService;<br><span class="hljs-keyword">import</span> java.util.concurrent.Executors;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> Administrator</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@Component</span><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TcpSocket</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Runnable</span> &#123;<br>    <span class="hljs-keyword">public</span> Integer port;<br>    <span class="hljs-keyword">private</span> ServerSocket server;<br>    <span class="hljs-keyword">private</span> ExecutorService threadPool;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">TcpSocket</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            port = <span class="hljs-number">8081</span>;<br>            threadPool = Executors.newCachedThreadPool();<br>            server = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(port);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            log.error(e.getMessage());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> server.accept();<br>                <span class="hljs-keyword">if</span> (socket != <span class="hljs-literal">null</span>) &#123;<br>                    <span class="hljs-type">SocketReceive</span> <span class="hljs-variable">socketReceive</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SocketReceive</span>(socket);<br>                    threadPool.submit(socketReceive);<br>                &#125;<br>            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>                e.printStackTrace();<br>            &#125;<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="在线连接"><a href="#在线连接" class="headerlink" title="在线连接"></a>在线连接</h2><p><code>AllClientsMap</code>类存放了所有的在线连接，通过<code>hostAddress</code>为<code>key</code>，<code>Socket</code>为<code>Value</code>。</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><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></pre></td><td class="code"><pre><code class="hljs Java"><span class="hljs-keyword">package</span> com.example.socket_demo.socket;<br><br><br><span class="hljs-keyword">import</span> lombok.extern.slf4j.Slf4j;<br><br><span class="hljs-keyword">import</span> java.net.Socket;<br><span class="hljs-keyword">import</span> java.util.concurrent.ConcurrentHashMap;<br><span class="hljs-keyword">import</span> java.util.concurrent.ConcurrentMap;<br><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">AllClientsMap</span> &#123;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 所有已连接设备</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> ConcurrentMap&lt;String, Socket&gt; ALLCLIENTS = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConcurrentHashMap</span>&lt;&gt;();<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 返回设备列表</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ConcurrentMap&lt;String, Socket&gt; <span class="hljs-title function_">getAllClients</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> ALLCLIENTS;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 通过key获取客户端</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Socket <span class="hljs-title function_">getSocketByKey</span><span class="hljs-params">(String key)</span> &#123;<br>        <span class="hljs-keyword">return</span> ALLCLIENTS.get(key);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 添加设备到列表</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> key</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> socket</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">put</span><span class="hljs-params">(String key, Socket socket)</span> &#123;<br>        ALLCLIENTS.put(key, socket);<br>        log.info(<span class="hljs-string">&quot;设备Key:&#123;&#125;========ip:&#123;&#125;已加入列表&quot;</span>, key, socket.getInetAddress().getHostAddress());<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 移除设备</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> key</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(String key)</span> &#123;<br>        ALLCLIENTS.remove(key);<br>        log.info(<span class="hljs-string">&quot;已移除设备Key:&#123;&#125;&quot;</span>, key);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 返回已连接设备数量</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-title function_">size</span><span class="hljs-params">()</span> &#123;<br>        log.info(<span class="hljs-string">&quot;当前设备数：&#123;&#125;&quot;</span>, ALLCLIENTS.size());<br>        <span class="hljs-keyword">return</span> ALLCLIENTS.size();<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 打印信息</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">print</span><span class="hljs-params">()</span> &#123;<br>        log.info(<span class="hljs-string">&quot;当前设备列表信息:长度：&#123;&#125;&quot;</span>, ALLCLIENTS.size());<br>        ALLCLIENTS.forEach((key, socket) -&gt; &#123;<br>            log.info(<span class="hljs-string">&quot;设备Key:&#123;&#125;========ip:&#123;&#125;&quot;</span>, key, socket.getInetAddress().getHostAddress());<br>        &#125;);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 是否包含</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> key</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">contains</span><span class="hljs-params">(String key)</span> &#123;<br>        <span class="hljs-keyword">return</span> ALLCLIENTS.containsKey(key);<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure><h2 id="创建SocketReceive"><a href="#创建SocketReceive" class="headerlink" title="创建SocketReceive"></a>创建SocketReceive</h2><p>在<code>SocketReceive</code>类中，我们可以执行相关的接收消息，以及业务操作；在第<code>64</code>行代码的位置，可以通过<code>ApplicationContext</code>获取<code>Spring Bean</code>执行业务代码</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><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><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br></pre></td><td class="code"><pre><code class="hljs Java"><span class="hljs-keyword">package</span> com.example.socket_demo.socket;<br><br><span class="hljs-keyword">import</span> lombok.extern.slf4j.Slf4j;<br><br><span class="hljs-keyword">import</span> java.io.DataInputStream;<br><span class="hljs-keyword">import</span> java.io.IOException;<br><span class="hljs-keyword">import</span> java.io.OutputStream;<br><span class="hljs-keyword">import</span> java.net.Socket;<br><br><span class="hljs-meta">@Slf4j</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SocketReceive</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Runnable</span> &#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">SocketReceive</span><span class="hljs-params">()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">SocketReceive</span><span class="hljs-params">(Socket socket)</span> &#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>            <span class="hljs-keyword">if</span> (<span class="hljs-literal">null</span> == socket) &#123;<br>                log.info(<span class="hljs-string">&quot;socket为空&quot;</span>);<br>                <span class="hljs-keyword">return</span>;<br>            &#125;<br>            <span class="hljs-type">boolean</span> <span class="hljs-variable">isClosed</span> <span class="hljs-operator">=</span> socket.isClosed();<br>            <span class="hljs-type">String</span> <span class="hljs-variable">hostAddress</span> <span class="hljs-operator">=</span> socket.getInetAddress().getHostAddress();<br>            <span class="hljs-keyword">if</span> (isClosed) &#123;<br>                log.info(<span class="hljs-string">&quot;socket检测到关闭了&quot;</span>);<br>                <span class="hljs-keyword">if</span> (AllClientsMap.contains(hostAddress)) &#123;<br>                    AllClientsMap.remove(hostAddress);<br>                    AllClientsMap.print();<br>                &#125;<br>                <span class="hljs-keyword">return</span>;<br>            &#125;<br>            <span class="hljs-type">String</span> <span class="hljs-variable">hostAddress</span> <span class="hljs-operator">=</span> socket.getInetAddress().getHostAddress();<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-comment">//建立客户端信息输入流</span><br>                <span class="hljs-type">DataInputStream</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DataInputStream</span>(socket.getInputStream());<br>                <span class="hljs-comment">//定义字节数组读取数据</span><br>                <span class="hljs-type">byte</span>[] bytes = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span>];<br>                <span class="hljs-type">int</span> <span class="hljs-variable">len</span> <span class="hljs-operator">=</span> in.read(bytes);<br>                <span class="hljs-keyword">if</span> (len == -<span class="hljs-number">1</span>) &#123;<br>                    <span class="hljs-keyword">return</span>;<br>                &#125;<br>                <span class="hljs-comment">//定义一个新数组copy，解决读取出来的数据字节不够全是0的问题</span><br>                <span class="hljs-type">byte</span>[] bytes1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[len];<br>                System.arraycopy(bytes, <span class="hljs-number">0</span>, bytes1, <span class="hljs-number">0</span>, len);<br>                log.info(<span class="hljs-string">&quot;客户端传的byte字节数组：&quot;</span> + printBytesByStringBuilder(bytes1));<br>                <span class="hljs-type">String</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(bytes1);<br>                log.info(<span class="hljs-string">&quot;客户端传的byte字节数组转换成字符串打印:&quot;</span> + s);<br>                <span class="hljs-comment">//转换hex数据</span><br>                <span class="hljs-type">String</span> <span class="hljs-variable">data</span> <span class="hljs-operator">=</span> byteArrayToHex(bytes1);<br>                log.info(<span class="hljs-string">&quot;接收的16进制数据:&quot;</span> + data);<br>                <span class="hljs-comment">//如果服务端没有保存该socket</span><br>                <span class="hljs-keyword">if</span>(!AllClientsMap.contains(hostAddress))&#123;<br>                    AllClientsMap.put(hostAddress, socket);<br>                    AllClientsMap.print();<br>                &#125;<br>                log.debug(<span class="hljs-string">&quot;客户端&quot;</span> + hostAddress + <span class="hljs-string">&quot;发送数据：&#123;&#125;&quot;</span>, data);<br>                <span class="hljs-comment">//执行业务</span><br>                System.out.println(<span class="hljs-string">&quot;执行业务&quot;</span>);<br><br>                <span class="hljs-comment">//从map中获取客户端发送消息</span><br>                response(AllClientsMap.getSocketByKey(hostAddress), data);<br><br>            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>                <span class="hljs-keyword">if</span> (AllClientsMap.contains(hostAddress)) &#123;<br>                    AllClientsMap.remove(hostAddress);<br>                    AllClientsMap.print();<br>                &#125;<br>                <span class="hljs-keyword">try</span> &#123;<br>                    socket.close();<br>                    log.error(<span class="hljs-string">&quot;&#123;&#125;断开连接&quot;</span>, hostAddress);<br>                    <span class="hljs-keyword">return</span>;<br>                &#125; <span class="hljs-keyword">catch</span> (IOException ioException) &#123;<br>                    log.error(ioException.getMessage());<br>                &#125;<br>            &#125;<br>        &#125;<br>    &#125;<br><br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 根据字节数组，输出对应的格式化字符串</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> bytes 字节数组</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span> 字节数组字符串</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">printBytesByStringBuilder</span><span class="hljs-params">(<span class="hljs-type">byte</span>[] bytes)</span> &#123;<br>        <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">stringBuilder</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">byte</span> aByte : bytes) &#123;<br>            stringBuilder.append(byte2String(aByte));<br>        &#125;<br>        <span class="hljs-keyword">return</span> stringBuilder.toString();<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">byte2String</span><span class="hljs-params">(<span class="hljs-type">byte</span> b)</span> &#123;<br>        <span class="hljs-keyword">return</span> String.format(<span class="hljs-string">&quot;%02x &quot;</span>, b);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 向socket发送消息</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> socket 对应socket</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> msg    消息</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">response</span><span class="hljs-params">(Socket socket, String msg)</span> &#123;<br>        log.debug(<span class="hljs-string">&quot;向设备IP：&#123;&#125;发送消息：&#123;&#125;&quot;</span>, socket.getInetAddress().getHostAddress(), msg);<br>        <span class="hljs-type">OutputStream</span> <span class="hljs-variable">outputStream</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>        <span class="hljs-keyword">try</span> &#123;<br>            outputStream = socket.getOutputStream();<br>            outputStream.write(hexStringToByteArray(msg));<br>        &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>            <span class="hljs-keyword">try</span> &#123;<br>                socket.close();<br>            &#125; <span class="hljs-keyword">catch</span> (IOException ioException) &#123;<br>                log.error(ioException.getMessage());<br>            &#125;<br>            log.error(e.getMessage());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 字节数组转字符串</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> bytes</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">byteArrayToHex</span><span class="hljs-params">(<span class="hljs-type">byte</span>[] bytes)</span> &#123;<br>        <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">index</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>, len = bytes.length; index &lt;= len - <span class="hljs-number">1</span>; index += <span class="hljs-number">1</span>) &#123;<br>            <span class="hljs-type">int</span> <span class="hljs-variable">char1</span> <span class="hljs-operator">=</span> ((bytes[index] &gt;&gt; <span class="hljs-number">4</span>) &amp; <span class="hljs-number">0xF</span>);<br>            <span class="hljs-type">char</span> <span class="hljs-variable">chara1</span> <span class="hljs-operator">=</span> Character.forDigit(char1, <span class="hljs-number">16</span>);<br>            <span class="hljs-type">int</span> <span class="hljs-variable">char2</span> <span class="hljs-operator">=</span> ((bytes[index]) &amp; <span class="hljs-number">0xF</span>);<br>            <span class="hljs-type">char</span> <span class="hljs-variable">chara2</span> <span class="hljs-operator">=</span> Character.forDigit(char2, <span class="hljs-number">16</span>);<br>            result.append(chara1);<br>            result.append(chara2);<br>        &#125;<br>        <span class="hljs-keyword">return</span> result.toString();<br>    &#125;<br><br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 16进制表示的字符串转换为字节数组</span><br><span class="hljs-comment">     *</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> hexString 16进制表示的字符串</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span> byte[] 字节数组</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">byte</span>[] hexStringToByteArray(String hexString) &#123;<br>        hexString = hexString.replaceAll(<span class="hljs-string">&quot; &quot;</span>, <span class="hljs-string">&quot;&quot;</span>);<br>        <span class="hljs-type">int</span> <span class="hljs-variable">len</span> <span class="hljs-operator">=</span> hexString.length();<br>        <span class="hljs-type">byte</span>[] bytes = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[len / <span class="hljs-number">2</span>];<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; len; i += <span class="hljs-number">2</span>) &#123;<br>            <span class="hljs-comment">// 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节</span><br>            bytes[i / <span class="hljs-number">2</span>] = (<span class="hljs-type">byte</span>) ((Character.digit(hexString.charAt(i), <span class="hljs-number">16</span>) &lt;&lt; <span class="hljs-number">4</span>) + Character<br>                    .digit(hexString.charAt(i + <span class="hljs-number">1</span>), <span class="hljs-number">16</span>));<br>        &#125;<br>        <span class="hljs-keyword">return</span> bytes;<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure><h2 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h2><p>通过继承<code>Spring</code>的<code>InitializingBean</code>类，重写<code>afterPropertiesSet</code>方法，这个方法将在所有的属性被初始化后调用。<br>然后会创建一个线程执行<code>ServerSocket</code>的监听，初始化我们的<code>TcpSocket</code>对象，一旦<code>Server</code>接收到了连接请求后，会创建一个<code>SocketReceive</code>对象将其扔给线程池执行，在线程池中的<code>SocketReceive</code>对象可以通过<code>ApplicationContext</code>获取<code>Spring Bean</code>执行业务代码。</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><code class="hljs Java"><span class="hljs-keyword">package</span> com.example.socket_demo.socket;<br><br><span class="hljs-keyword">import</span> org.springframework.beans.factory.InitializingBean;<br><span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;<br><span class="hljs-keyword">import</span> org.springframework.stereotype.Component;<br><br><span class="hljs-meta">@Component</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SpringFinishedListener</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">InitializingBean</span> &#123;<br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> TcpSocket tcpsocket;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">afterPropertiesSet</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-type">Thread</span> <span class="hljs-variable">serverThread</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Thread</span>(tcpsocket);<br>        serverThread.start();<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure><h2 id="测试工具"><a href="#测试工具" class="headerlink" title="测试工具"></a>测试工具</h2><p>这里推荐一个测试工具，还挺好用的。<a href="https://github.com/gujiniCY/gujiniCY.github.io/raw/main/2022/10/27/SpringBoot%E6%95%B4%E5%90%88Socket/PortHelper(%E5%8D%95%E7%89%87%E6%9C%BA%E5%A4%9A%E5%8A%9F%E8%83%BD%E8%B0%83%E8%AF%95%E5%8A%A9%E6%89%8B).exe" title="单片机多功能调试助手">下载连接</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;前言&quot;&gt;&lt;a href=&quot;#前言&quot; class=&quot;headerlink&quot; title=&quot;前言&quot;&gt;&lt;/a&gt;前言&lt;/h2&gt;&lt;p&gt;前段时间公司一个物联网项目需要通过TCP连接设备收发消息，现在我把代码整理出来，分享一下。&lt;/p&gt;
&lt;p&gt;源代码已发布在&lt;a href=&quot;h</summary>
      
    
    
    
    <category term="Java" scheme="https://www.songhaozhi.com/categories/Java/"/>
    
    <category term="Socket" scheme="https://www.songhaozhi.com/categories/Socket/"/>
    
    <category term="TCP" scheme="https://www.songhaozhi.com/categories/TCP/"/>
    
    
    <category term="Java" scheme="https://www.songhaozhi.com/tags/Java/"/>
    
    <category term="Socket" scheme="https://www.songhaozhi.com/tags/Socket/"/>
    
    <category term="TCP" scheme="https://www.songhaozhi.com/tags/TCP/"/>
    
  </entry>
  
  <entry>
    <title>使用coding持续集成SpringBoot项目</title>
    <link href="https://www.songhaozhi.com/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/"/>
    <id>https://www.songhaozhi.com/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/</id>
    <published>2022-10-17T02:30:56.000Z</published>
    <updated>2022-11-14T07:57:13.768Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>公司项目使用Coding进行管理，每次打包部署都需要经历以下流程</p><ul><li>代码提交</li><li>项目打包</li><li>登录服务器</li><li>上传应用到服务器</li><li>执行部署脚本</li><li>发现Bug -&gt;修改Bug -&gt; 重复第一道流程</li></ul><p>了解过Jenkins等持续集成工具后，查看到Coding也有相关服务，并且Coding还提供一台云主机来进行构建操作。</p><p>如果你也长期经历以上流程，强烈建议你了解一下持续集成，因为手动部署实在是麻烦又耗时，使用持续集成后省下的时间又可以多写两行Bug了🤪</p><h2 id="需求"><a href="#需求" class="headerlink" title="需求"></a>需求</h2><p>我们希望每次写完代码，提交到主分支以后，项目能够自动编译打包，上传至服务器，并自动重启应用</p><h2 id="前期工作"><a href="#前期工作" class="headerlink" title="前期工作"></a>前期工作</h2><h3 id="凭证管理"><a href="#凭证管理" class="headerlink" title="凭证管理"></a>凭证管理</h3><p>官方文档，凭证管理 <a href="https://coding.net/help/docs/project-settings/credential.html">https://coding.net/help/docs/project-settings/credential.html</a></p><h4 id="生成Rsa私钥"><a href="#生成Rsa私钥" class="headerlink" title="生成Rsa私钥"></a>生成Rsa私钥</h4><p>登录服务器，生成Rsa私钥</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">ssh-keygen -t rsa</span><br></code></pre></td></tr></table></figure><p>生成好的文件在<code>/root/.ssh</code>路径下</p><p>将<code>id_rsa.pub</code>添加到<code>authorized_keys</code>文件中，并重启sshd服务</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">systemctl  restart sshd</span><br></code></pre></td></tr></table></figure><h4 id="添加至Coding凭证管理"><a href="#添加至Coding凭证管理" class="headerlink" title="添加至Coding凭证管理"></a>添加至Coding凭证管理</h4><p>1.将id_rsa文件中的内容添加至Coding</p><p><img src="/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/2022-10-17-11-26-16.png"></p><p>2.在录入凭据页面，输入相关信息</p><ul><li>选择「SSH 私钥」凭据类型</li><li>输入凭据名称，必填项，长度不超过 255 个字符</li><li>输入 SSH 私钥，必填项</li><li>输入私钥口令，非必填</li><li>输入描述，非必填</li></ul><p>3.勾选需要授权的持续集成功能。只有进行凭据授权后，在使用 CODING 持续集成功能模块创建构建计划时才有权限使用该凭据。</p><p>4.点击「创建」即可完成创建。录入成功的凭据会显示在凭据管理页面。</p><h3 id="白名单释放"><a href="#白名单释放" class="headerlink" title="白名单释放"></a>白名单释放</h3><p>因为我们使用的是阿里云的服务器，所以需要释放Coding的IP，如果你使用的不是阿里云可忽略</p><p>Coding文档：<a href="https://coding.net/help/docs/ci/faq/job-fail.html#aliyun">https://coding.net/help/docs/ci/faq/job-fail.html#aliyun</a></p><p>执行 SSH 命令访问阿里云主机时提示 Connection reset 错误。</p><p>此问题是阿里云侧白名单未放行 CODING IP 所致。前往阿里云「安全管控平台」→「安全管控」→「新增访问白名单」，将构建机的 IP 加入至白名单中可以防止其在访问云主机时被拦截。</p><p>CODING 构建机所使用的出口 IP 如下：</p><figure class="highlight accesslog"><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><code class="hljs accesslog"># 中国上海节点<br> <br><span class="hljs-number">111.231.92.100</span><br> <br><span class="hljs-number">81.68.101.44</span><br> <br># 中国香港节点<br> <br><span class="hljs-number">124.156.164.25</span><br> <br><span class="hljs-number">119.28.15.65</span><br> <br># 美国硅谷节点<br> <br><span class="hljs-number">170.106.136.17</span><br> <br><span class="hljs-number">170.106.83.77</span><br></code></pre></td></tr></table></figure><h2 id="构建计划"><a href="#构建计划" class="headerlink" title="构建计划"></a>构建计划</h2><h3 id="创建构建计划"><a href="#创建构建计划" class="headerlink" title="创建构建计划"></a>创建构建计划</h3><p>首先进入Coding的项目中，找到持续集成-构建计划，新建构建计划</p><p><img src="/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/2022-10-17-11-01-21.png"></p><p>点击自定义构建流程<br><img src="/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/2022-10-17-11-04-03.png"></p><h3 id="Jenkinsfile"><a href="#Jenkinsfile" class="headerlink" title="Jenkinsfile"></a>Jenkinsfile</h3><p>创建自定义流程以后我们开始编写Jenkinsfile</p><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><code class="hljs pipeline"><br>pipeline &#123;<br>  agent any<br>  stages &#123;<br>    stage(&#x27;检出&#x27;) &#123;<br>      steps &#123;<br>        checkout([<br>          $class: &#x27;GitSCM&#x27;,<br>          branches: [[name: GIT_BUILD_REF]],<br>          userRemoteConfigs: [[<br>            url: GIT_REPO_URL,<br>            credentialsId: CREDENTIALS_ID<br>          ]]])<br>        &#125;<br>      &#125;<br><br>      stage(&#x27;编译&#x27;) &#123;<br>        steps &#123;<br>          echo &#x27;构建中...&#x27;<br>          sh &#x27;mvn clean package&#x27;<br>          echo &#x27;构建完成&#x27;<br>          echo &#x27;当前所在位置:&#x27;<br>          sh &#x27;&#x27;&#x27;pwd<br>ls&#x27;&#x27;&#x27;<br>          sh &#x27;&#x27;&#x27;ls $&#123;project_target_path&#125;<br>&#x27;&#x27;&#x27;<br>          sh &#x27;&#x27;&#x27;tar -zcf /root/workspace/tmp.tar.gz $&#123;project_target_path&#125;/*.jar<br>ls /root/workspace/&#x27;&#x27;&#x27;<br>        &#125;<br>      &#125;<br><br>      stage(&#x27;重启应用&#x27;) &#123;<br>        steps &#123;<br>          echo &#x27;开始发送文件到远端服务器...&#x27;<br>          script &#123;<br>            def remote = [:]<br>            remote.name = &#x27;web-server&#x27;<br>            remote.allowAnyHosts = true<br>            remote.host = host<br>            remote.port = port as Integer<br>            remote.user = user<br>            // 把「CODING 凭据管理」中的「凭据 ID」填入 credentialsId，而 id_rsa 无需修改<br>            withCredentials([sshUserPrivateKey(credentialsId: credentialsId, keyFileVariable: &#x27;id_rsa&#x27;)]) &#123;<br>              remote.identityFile = id_rsa<br>              // SSH 上传文件到远端服务器<br>              sshPut remote: remote, from: &quot;/root/workspace/tmp.tar.gz&quot;, into: &#x27;/tmp/&#x27;<br>              // 解压缩<br>              sshCommand remote: remote, command: &quot;tar -zxf /tmp/tmp.tar.gz -C /tmp/&quot;<br>              //复制文件到运行目录<br>              sshCommand remote: remote, sudo: true, command: &quot;cp -R /tmp/$&#123;project_target_path&#125;/* $&#123;project_path&#125;&quot;<br>              //执行脚本重启应用<br>              sshCommand remote: remote, sudo: true, command: sh_path_command<br><br><br>            &#125;<br>          &#125;<br><br>          echo &#x27;部署成功...&#x27;<br>        &#125;<br>      &#125;<br><br>    &#125;<br>  &#125;<br></code></pre></td></tr></table></figure><p>Jenkinsfile文件中有七个环境变量字段，如下</p><table><thead><tr><th align="left">字段值</th><th align="center">字段名称</th><th align="right">字段注释</th><th align="right">示例</th></tr></thead><tbody><tr><td align="left">project_path</td><td align="center">项目存放的目录地址</td><td align="right">jar在服务器上实际存放的地址</td><td align="right">&#x2F;usr&#x2F;local&#x2F;java&#x2F;demo</td></tr><tr><td align="left">sh_path_command</td><td align="center">需要执行的sh命令</td><td align="right">一般是 sh 脚本所在位置加执行的操作</td><td align="right">sh &#x2F;usr&#x2F;local&#x2F;java&#x2F;demo&#x2F;start.sh restart  此命令是执行&#x2F;usr&#x2F;local&#x2F;java&#x2F;demo目录下start.sh脚本的restart操作</td></tr><tr><td align="left">host:目标服务器地址</td><td align="center">服务器IP地址</td><td align="right">111.111.111.111</td><td align="right"></td></tr><tr><td align="left">port</td><td align="center">SSH端口号</td><td align="right">端口号</td><td align="right">22</td></tr><tr><td align="left">user</td><td align="center">SSH用户名</td><td align="right">登录用户名</td><td align="right">root</td></tr><tr><td align="left">credentialsId</td><td align="center">SSH登录凭据</td><td align="right">ssh登录凭证</td><td align="right">选择项，需要配置私钥并添加至coding凭证管理中</td></tr><tr><td align="left">project_target_path</td><td align="center">jar包所在目录</td><td align="right">执行打包命令后jar所在的目录</td><td align="right">demo&#x2F;target</td></tr></tbody></table><p>以上环境变量需要添加至该构建计划的【变量与缓存】中，如图:</p><p><img src="/2022/10/17/%E4%BD%BF%E7%94%A8coding%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90SpringBoot%E9%A1%B9%E7%9B%AE/2022-10-17-11-17-02.png"></p><p>我们的项目采用Maven构建，我勾选上了缓存Maven目录，这样每次构建就不需要重复下载依赖了，速度更快</p><h3 id="启动脚本"><a href="#启动脚本" class="headerlink" title="启动脚本"></a>启动脚本</h3><p>此脚本来自ruoyi-vue项目,脚本内容需要调整<code>$AppName</code>和<code>$APP_HOME</code>参数，<code>$JVM_OPTS</code>参数可酌情调整</p><figure class="highlight bash"><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></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-meta">#!/bin/sh</span><br><span class="hljs-comment"># ./start.sh start 启动</span><br><span class="hljs-comment"># ./start.sh stop 停止</span><br><span class="hljs-comment"># ./start.sh restart 重启</span><br><span class="hljs-comment"># ./start.sh status 状态</span><br>AppName=jenkins_demo-0.0.1-SNAPSHOT.jar<br><span class="hljs-comment"># JVM参数</span><br>JVM_OPTS=<span class="hljs-string">&quot;-Dname=<span class="hljs-variable">$AppName</span>  -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC&quot;</span><br><span class="hljs-comment">#App所在目录</span><br>APP_HOME=<span class="hljs-string">&quot;/usr/local/java/demo&quot;</span><br>LOG_PATH=<span class="hljs-variable">$APP_HOME</span>/logs/<span class="hljs-variable">$AppName</span>.<span class="hljs-built_in">log</span><br><br><span class="hljs-keyword">if</span> [ <span class="hljs-string">&quot;<span class="hljs-variable">$1</span>&quot;</span> = <span class="hljs-string">&quot;&quot;</span> ];<br><span class="hljs-keyword">then</span><br>    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">&quot;\033[0;31m 未输入操作名 \033[0m  \033[0;34m &#123;start|stop|restart|status&#125; \033[0m&quot;</span><br>    <span class="hljs-built_in">exit</span> 1<br><span class="hljs-keyword">fi</span><br><br><span class="hljs-keyword">if</span> [ <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span>&quot;</span> = <span class="hljs-string">&quot;&quot;</span> ];<br><span class="hljs-keyword">then</span><br>    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">&quot;\033[0;31m 未输入应用名 \033[0m&quot;</span><br>    <span class="hljs-built_in">exit</span> 1<br><span class="hljs-keyword">fi</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">start</span></span>()<br>&#123;<br>    <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;开始执行start&quot;</span><br>   <span class="hljs-built_in">cd</span> <span class="hljs-variable">$APP_HOME</span><br>   <span class="hljs-built_in">nohup</span> java -jar  <span class="hljs-variable">$APP_HOME</span>/<span class="hljs-variable">$AppName</span> &gt; nohup.out &amp; 2&gt;&amp;1 &amp;<br>    <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;结束执行start&quot;</span><br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">stop</span></span>()<br>&#123;<br>    <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Stop <span class="hljs-variable">$AppName</span>&quot;</span><br><br>PID=<span class="hljs-string">&quot;&quot;</span><br><span class="hljs-function"><span class="hljs-title">query</span></span>()&#123;<br>PID=`ps -ef |grep java|grep <span class="hljs-variable">$AppName</span>|grep -v grep|awk <span class="hljs-string">&#x27;&#123;print $2&#125;&#x27;</span>`<br>&#125;<br><br>query<br><span class="hljs-keyword">if</span> [ x<span class="hljs-string">&quot;<span class="hljs-variable">$PID</span>&quot;</span> != x<span class="hljs-string">&quot;&quot;</span> ]; <span class="hljs-keyword">then</span><br><span class="hljs-built_in">kill</span> -TERM <span class="hljs-variable">$PID</span><br><span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span> (pid:<span class="hljs-variable">$PID</span>) exiting...&quot;</span><br><span class="hljs-keyword">while</span> [ x<span class="hljs-string">&quot;<span class="hljs-variable">$PID</span>&quot;</span> != x<span class="hljs-string">&quot;&quot;</span> ]<br><span class="hljs-keyword">do</span><br><span class="hljs-built_in">sleep</span> 1<br>query<br><span class="hljs-keyword">done</span><br><span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span> exited.&quot;</span><br><span class="hljs-keyword">else</span><br><span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span> already stopped.&quot;</span><br><span class="hljs-keyword">fi</span><br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">restart</span></span>()<br>&#123;<br>    stop<br>    <span class="hljs-built_in">sleep</span> 2<br>    start<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">status</span></span>()<br>&#123;<br>    PID=`ps -ef |grep java|grep <span class="hljs-variable">$AppName</span>|grep -v grep|<span class="hljs-built_in">wc</span> -l`<br>    <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$PID</span> != 0 ];<span class="hljs-keyword">then</span><br>        <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span> is running...&quot;</span><br>    <span class="hljs-keyword">else</span><br>        <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;<span class="hljs-variable">$AppName</span> is not running...&quot;</span><br>    <span class="hljs-keyword">fi</span><br>&#125;<br><br><span class="hljs-keyword">case</span> <span class="hljs-variable">$1</span> <span class="hljs-keyword">in</span><br>    start)<br>    start;;<br>    stop)<br>    stop;;<br>    restart)<br>    restart;;<br>    status)<br>    status;;<br>    *)<br><br><span class="hljs-keyword">esac</span><br></code></pre></td></tr></table></figure><h2 id="疑问-x2F-讨论"><a href="#疑问-x2F-讨论" class="headerlink" title="疑问&#x2F;讨论"></a>疑问&#x2F;讨论</h2><p>如果使用Nginx配置了负载均衡，部署了多个Jar，该持续集成应该怎么实现呢？评论区有答案吗？</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;前言&quot;&gt;&lt;a href=&quot;#前言&quot; class=&quot;headerlink&quot; title=&quot;前言&quot;&gt;&lt;/a&gt;前言&lt;/h2&gt;&lt;p&gt;公司项目使用Coding进行管理，每次打包部署都需要经历以下流程&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码提交&lt;/li&gt;
&lt;li&gt;项目打包&lt;/li&gt;
</summary>
      
    
    
    
    <category term="持续集成" scheme="https://www.songhaozhi.com/categories/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/"/>
    
    <category term="Coding" scheme="https://www.songhaozhi.com/categories/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/Coding/"/>
    
    
    <category term="Coding" scheme="https://www.songhaozhi.com/tags/Coding/"/>
    
    <category term="持续集成" scheme="https://www.songhaozhi.com/tags/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/"/>
    
  </entry>
  
  <entry>
    <title>使用acme.sh来申请SSL证书</title>
    <link href="https://www.songhaozhi.com/2022/09/23/%E4%BD%BF%E7%94%A8acme-sh%E6%9D%A5%E7%94%B3%E8%AF%B7SSL%E8%AF%81%E4%B9%A6/"/>
    <id>https://www.songhaozhi.com/2022/09/23/%E4%BD%BF%E7%94%A8acme-sh%E6%9D%A5%E7%94%B3%E8%AF%B7SSL%E8%AF%81%E4%B9%A6/</id>
    <published>2022-09-23T06:12:27.000Z</published>
    <updated>2022-11-14T07:57:13.768Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p><code>acme.sh</code> 实现了 <code>acme</code> 协议, 可以从 <code>letsencrypt</code> 生成免费的证书.</p><p>官方文档：<a href="https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E">https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E</a></p><p>本篇文章以Nginx为例子，来实现获取SSL证书，以及配置Nginx</p><h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><p>安装很简单, 一个命令:</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs vim">curl https://<span class="hljs-built_in">get</span>.acme.<span class="hljs-keyword">sh</span> | <span class="hljs-keyword">sh</span> -s email=my@example.<span class="hljs-keyword">com</span><br></code></pre></td></tr></table></figure><div class="note note-info">            <p><code>my@example.com</code>是你的邮箱地址</p>          </div><p>创建 一个 shell 的 alias, 例如 .bashrc，方便你的使用: </p><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata">alias acme.<span class="hljs-keyword">sh</span>=~/.acme.<span class="hljs-keyword">sh</span>/acme.<span class="hljs-keyword">sh</span><br></code></pre></td></tr></table></figure><p>普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:</p><ol><li>把 acme.sh 安装到你的 home 目录下:</li></ol><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arcade">~<span class="hljs-regexp">/.acme.sh/</span><br></code></pre></td></tr></table></figure><ol start="2"><li>自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.</li></ol><p>更高级的安装选项请参考: <a href="https://github.com/Neilpang/acme.sh/wiki/How-to-install">https://github.com/Neilpang/acme.sh/wiki/How-to-install</a></p><h1 id="配置Nginx"><a href="#配置Nginx" class="headerlink" title="配置Nginx"></a>配置Nginx</h1><p>先把Nginx配置文件写好，让这个域名可以通过http访问</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><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-section">server</span> &#123;<br><span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;<br>       <span class="hljs-attribute">server_name</span>  你的域名;<br>       <span class="hljs-section">location</span> / &#123;<br>          <span class="hljs-comment">#转发的ip和端口 </span><br>          <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:8080;<br>       &#125;<br>       <span class="hljs-attribute">error_page</span>   <span class="hljs-number">500</span> <span class="hljs-number">502</span> <span class="hljs-number">503</span> <span class="hljs-number">504</span>  /50x.html;<br>       <span class="hljs-section">location</span> = /50x.html &#123;<br>           <span class="hljs-attribute">root</span>   html;<br>       &#125;<br>   &#125;<br></code></pre></td></tr></table></figure><h1 id="生成证书"><a href="#生成证书" class="headerlink" title="生成证书"></a>生成证书</h1><p>关于生成证书，官方的例子有apache、nginx、手动 dns 的方式，我这里只演示Nginx的方式</p><p>官方文档上这样写的</p><blockquote><p><a href="https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E#1-http-%E6%96%B9%E5%BC%8F%E9%9C%80%E8%A6%81%E5%9C%A8%E4%BD%A0%E7%9A%84%E7%BD%91%E7%AB%99%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%94%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6-%E6%9D%A5%E9%AA%8C%E8%AF%81%E4%BD%A0%E7%9A%84%E5%9F%9F%E5%90%8D%E6%89%80%E6%9C%89%E6%9D%83%E5%AE%8C%E6%88%90%E9%AA%8C%E8%AF%81-%E7%84%B6%E5%90%8E%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%94%9F%E6%88%90%E8%AF%81%E4%B9%A6%E4%BA%86">https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E#1-http-%E6%96%B9%E5%BC%8F%E9%9C%80%E8%A6%81%E5%9C%A8%E4%BD%A0%E7%9A%84%E7%BD%91%E7%AB%99%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%94%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6-%E6%9D%A5%E9%AA%8C%E8%AF%81%E4%BD%A0%E7%9A%84%E5%9F%9F%E5%90%8D%E6%89%80%E6%9C%89%E6%9D%83%E5%AE%8C%E6%88%90%E9%AA%8C%E8%AF%81-%E7%84%B6%E5%90%8E%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%94%9F%E6%88%90%E8%AF%81%E4%B9%A6%E4%BA%86</a></p></blockquote><blockquote><p>如果你用的 nginx服务器, 或者反代, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:</p></blockquote><p>执行以下命令：</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">acme<span class="hljs-selector-class">.sh</span> <span class="hljs-attr">--issue</span> -d 你的域名<span class="hljs-selector-class">.com</span> <span class="hljs-attr">--nginx</span><br></code></pre></td></tr></table></figure><p>生成好的证书会存放在<code>~/.acme.sh/example.com</code>下</p><h1 id="copy-x2F-安装证书"><a href="#copy-x2F-安装证书" class="headerlink" title="copy&#x2F;安装证书"></a>copy&#x2F;安装证书</h1><p>前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.</p><p>注意, 默认生成的证书都放在安装目录下: ~&#x2F;.acme.sh&#x2F;, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx&#x2F;apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.</p><p>正确的使用方法是使用 –install-cert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:</p><figure class="highlight gradle"><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><code class="hljs gradle">acme.sh --force --install-cert <br>-d example.com <br>--fullchain-<span class="hljs-keyword">file</span> <span class="hljs-regexp">/etc/</span>nginx<span class="hljs-regexp">/ssl/</span>example.com.crt <br>--key-<span class="hljs-keyword">file</span>  <span class="hljs-regexp">/etc/</span>nginx<span class="hljs-regexp">/ssl/</span>example.com.key <br>--reloadcmd <span class="hljs-string">&quot;service nginx force-reload&quot;</span> &gt; <span class="hljs-regexp">/dev/</span><span class="hljs-keyword">null</span> <br></code></pre></td></tr></table></figure><div class="note note-info">            <p>–install-cert: 这个参数代表cpoy<br>-d: 你的域名<br>–key-file: copy你的私钥文件,需要和nginx指定的一致<br>–fullchain-file: copy你的证书链文件(此文件包含自己和中间ca机构的证书),需要和nginx指定的一致<br>–reloadcmd: 指定重新加载证书的命令</p>          </div><p>(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)</p><p>Nginx 的配置 ssl_certificate 使用 &#x2F;etc&#x2F;nginx&#x2F;ssl&#x2F;fullchain.cer ，而非 &#x2F;etc&#x2F;nginx&#x2F;ssl&#x2F;<domain>.cer ，否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。</domain></p><p>–install-cert命令可以携带很多参数, 来指定目标文件. 并且可以指定 reloadcmd, 当证书更新以后, reloadcmd会被自动调用,让服务器生效.</p><p>详细参数请参考: <a href="https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc">https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc</a></p><p>值得注意的是, 这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用.</p><h1 id="修改Nginx配置文件"><a href="#修改Nginx配置文件" class="headerlink" title="修改Nginx配置文件"></a>修改Nginx配置文件</h1><p>执行上面的命令以后，会发现在<code>/etc/nginx/ssl</code>目录下会多出两个文件，我们需要把这两个文件在Nginx配置文件中配置好</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><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></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-section">server</span> &#123;<br><span class="hljs-attribute">listen</span> <span class="hljs-number">443</span> ssl;<br>        <span class="hljs-attribute">server_name</span>  example.com;<br>        <span class="hljs-attribute">ssl</span> <span class="hljs-literal">on</span>;<br>        <span class="hljs-attribute">ssl_certificate</span>      /etc/nginx/ssl/example.com.crt;<br>        <span class="hljs-attribute">ssl_certificate_key</span>  /etc/nginx/ssl/example.com.key; <br>        <span class="hljs-attribute">ssl_session_timeout</span> <span class="hljs-number">5m</span>;<br>        <span class="hljs-attribute">ssl_session_cache</span> shared:SSL:<span class="hljs-number">50m</span>;<br>        <span class="hljs-attribute">ssl_protocols</span> SSLv3 SSLv2 TLSv1 TLSv1.<span class="hljs-number">1</span> TLSv1.<span class="hljs-number">2</span>; <span class="hljs-comment">#按照这个协议配置</span><br>        <span class="hljs-attribute">ssl_ciphers</span> ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;<br>        <span class="hljs-attribute">ssl_prefer_server_ciphers</span> <span class="hljs-literal">on</span>;<br>        <span class="hljs-section">location</span> / &#123;<br>           <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:8080;<br>           <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;<br>           <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;<br>           <span class="hljs-attribute">proxy_set_header</span> REMOTE-HOST <span class="hljs-variable">$remote_addr</span>;<br>           <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;<br>        &#125;<br>        <span class="hljs-attribute">error_page</span>   <span class="hljs-number">500</span> <span class="hljs-number">502</span> <span class="hljs-number">503</span> <span class="hljs-number">504</span>  /50x.html;<br>        <span class="hljs-section">location</span> = /50x.html &#123;<br>            <span class="hljs-attribute">root</span>   html;<br>        &#125;<br>    &#125;<br></code></pre></td></tr></table></figure><p>Nginx配置好后重启Nginx，访问你的域名。</p><h1 id="更新证书"><a href="#更新证书" class="headerlink" title="更新证书"></a>更新证书</h1><p>目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.</p><p>请确保 cronjob 正确安装, 看起来是类似这样的:</p><figure class="highlight gradle"><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><code class="hljs gradle">crontab  -l<br><br><span class="hljs-number">56</span> * * * * <span class="hljs-string">&quot;/root/.acme.sh&quot;</span><span class="hljs-regexp">/acme.sh --cron --home &quot;/</span>root<span class="hljs-regexp">/.acme.sh&quot; &gt; /</span>dev/<span class="hljs-keyword">null</span><br></code></pre></td></tr></table></figure><h1 id="其他常用命令"><a href="#其他常用命令" class="headerlink" title="其他常用命令"></a>其他常用命令</h1><p><code>acme.sh --info -d example.com </code>：查看已安装证书信息</p><p><code>acme.sh --list</code>: 列出所有证书</p><p><code>acme.sh --renew -d soulchild.site -d *.soulchild.site --force</code>: 手动强制更新证书</p><p><code>acme.sh --renew-all</code>: 手动更新所有证书</p><p><code>acme.sh --revoke</code>: 撤销证书</p><p><code>acme.sh --remove -d soulchild.site</code>: 删除证书</p><p><code>acme.sh --cron</code>: 通过cronjob更新所有证书。</p><p><code>acme.sh --upgrade</code>: 升级acme.sh</p><p><code>acme.sh --uninstall</code>: 卸载acme.sh</p><h1 id="更新acme-sh"><a href="#更新acme-sh" class="headerlink" title="更新acme.sh"></a>更新acme.sh</h1><p><code>acme.sh --upgrade</code>：升级到最新版</p><p><code>acme.sh --upgrade --auto-upgrade</code>：开启自动更新</p><p><code>acme.sh --upgrade --auto-upgrade  0</code>：关闭自动更新</p><h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><blockquote><p><a href="https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E">https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E</a></p></blockquote><blockquote><p><a href="https://github.com/oneinstack/oneinstack/blob/master/vhost.sh#L265">https://github.com/oneinstack/oneinstack/blob/master/vhost.sh#L265</a></p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h1&gt;&lt;p&gt;&lt;code&gt;acme.sh&lt;/code&gt; 实现了 &lt;code&gt;acme&lt;/code&gt; 协议, 可以从 &lt;code&gt;letsencrypt&lt;/</summary>
      
    
    
    
    <category term="Nginx" scheme="https://www.songhaozhi.com/categories/Nginx/"/>
    
    <category term="Centos" scheme="https://www.songhaozhi.com/categories/Centos/"/>
    
    <category term="SSL" scheme="https://www.songhaozhi.com/categories/SSL/"/>
    
    
    <category term="Nginx" scheme="https://www.songhaozhi.com/tags/Nginx/"/>
    
    <category term="Centos" scheme="https://www.songhaozhi.com/tags/Centos/"/>
    
    <category term="SSL" scheme="https://www.songhaozhi.com/tags/SSL/"/>
    
  </entry>
  
  <entry>
    <title>CentOS安装Nginx</title>
    <link href="https://www.songhaozhi.com/2022/09/23/CentOS%E5%AE%89%E8%A3%85Nginx/"/>
    <id>https://www.songhaozhi.com/2022/09/23/CentOS%E5%AE%89%E8%A3%85Nginx/</id>
    <published>2022-09-23T05:51:29.000Z</published>
    <updated>2022-11-14T07:57:13.740Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器，同时也提供了IMAP&#x2F;POP3&#x2F;SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点（俄文：Рамблер）开发的。</p><p>其将源代码以类BSD许可证的形式发布，因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名。</p><p>Nginx是一款轻量级的Web 服务器&#x2F;反向代理服务器及电子邮件（IMAP&#x2F;POP3）代理服务器，在BSD-like 协议下发行。其特点是占有内存少，并发能力强，事实上nginx的并发能力在同类型的网页服务器中表现较好。</p><h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><h2 id="添加Nginx到YUM源"><a href="#添加Nginx到YUM源" class="headerlink" title="添加Nginx到YUM源"></a>添加Nginx到YUM源</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm<br></code></pre></td></tr></table></figure><h2 id="安装Nginx"><a href="#安装Nginx" class="headerlink" title="安装Nginx"></a>安装Nginx</h2><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">yum -y <span class="hljs-keyword">install</span> nginx<br></code></pre></td></tr></table></figure><h2 id="启动Nginx"><a href="#启动Nginx" class="headerlink" title="启动Nginx"></a>启动Nginx</h2><p>刚安装的Nginx不会自动启动</p><figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs crmsh">systemctl <span class="hljs-literal">start</span> nginx.service<br></code></pre></td></tr></table></figure><h2 id="查看Nginx状态"><a href="#查看Nginx状态" class="headerlink" title="查看Nginx状态"></a>查看Nginx状态</h2><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><br>systemctl <span class="hljs-built_in">enable</span> nginx.service<br></code></pre></td></tr></table></figure><h2 id="设置开机自启"><a href="#设置开机自启" class="headerlink" title="设置开机自启"></a>设置开机自启</h2><figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs fortran">systemctl <span class="hljs-keyword">status</span> nginx.service<br></code></pre></td></tr></table></figure><h2 id="停止Nginx"><a href="#停止Nginx" class="headerlink" title="停止Nginx"></a>停止Nginx</h2><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arduino">systemctl stop nginx.service<br></code></pre></td></tr></table></figure><h2 id="重启Nginx"><a href="#重启Nginx" class="headerlink" title="重启Nginx"></a>重启Nginx</h2><figure class="highlight maxima"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs maxima">systemctl <span class="hljs-built_in">restart</span> nginx.service<br></code></pre></td></tr></table></figure><h2 id="重新读取nginx配置"><a href="#重新读取nginx配置" class="headerlink" title="重新读取nginx配置"></a>重新读取nginx配置</h2><p>这个最常用, 不用停止nginx服务就能使修改的配置生效</p><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">systemctl <span class="hljs-keyword">reload</span> nginx.service<br></code></pre></td></tr></table></figure><h2 id="网站文件存放默认目录"><a href="#网站文件存放默认目录" class="headerlink" title="网站文件存放默认目录"></a>网站文件存放默认目录</h2><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-regexp">/usr/</span>share<span class="hljs-regexp">/nginx/</span>html<br></code></pre></td></tr></table></figure><h2 id="Nginx配置文件路径"><a href="#Nginx配置文件路径" class="headerlink" title="Nginx配置文件路径"></a>Nginx配置文件路径</h2><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-regexp">/etc/</span>nginx/nginx.conf<br></code></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h1&gt;&lt;p&gt;Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器，同时也提供了IMAP&amp;#x2F;POP3&amp;#x2F;SMTP</summary>
      
    
    
    
    <category term="Nginx" scheme="https://www.songhaozhi.com/categories/Nginx/"/>
    
    <category term="Centos" scheme="https://www.songhaozhi.com/categories/Centos/"/>
    
    
    <category term="Nginx" scheme="https://www.songhaozhi.com/tags/Nginx/"/>
    
    <category term="Centos" scheme="https://www.songhaozhi.com/tags/Centos/"/>
    
  </entry>
  
  <entry>
    <title>使用Windows内置虚拟机Hyper-v安装CentOS</title>
    <link href="https://www.songhaozhi.com/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/"/>
    <id>https://www.songhaozhi.com/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/</id>
    <published>2022-09-08T07:02:04.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="下载Centos"><a href="#下载Centos" class="headerlink" title="下载Centos"></a>下载Centos</h2><p><a href="http://mirrors.aliyun.com/centos/7/isos/x86_64/">http://mirrors.aliyun.com/centos/7/isos/x86_64/</a></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/mirrors.png"></p><h2 id="开启Hyper-V"><a href="#开启Hyper-V" class="headerlink" title="开启Hyper-V"></a>开启Hyper-V</h2><p>在Windows中搜索<code>启用或关闭Windows功能</code>并打开</p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/search.png"></p><p>勾选<code>Hyper-V</code></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/open.png"></p><p>在应用程序中找到<code>hyper-v管理器</code></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/hyper.png"></p><h2 id="虚拟交换机"><a href="#虚拟交换机" class="headerlink" title="虚拟交换机"></a>虚拟交换机</h2><p>网上其他文章在新建虚拟机之前会先创建虚拟交换机，但是我操作的时候，创建完虚拟交换机以后，本机会出现无网络的情况</p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/tips.png"></p><p>所以我就不创建虚拟交换机了</p><h2 id="新建虚拟机"><a href="#新建虚拟机" class="headerlink" title="新建虚拟机"></a>新建虚拟机</h2><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/create.png"></p><p>直接点击下一步<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-36-13.png"></p><p>设置虚拟机名称以及存放位置<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-36-54.png"></p><p>选择第一代<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-37-45.png"></p><p>分配内存大小，按你的需求进行分配<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-38-08.png"></p><p>网络连接如果是新建了虚拟交换机就选择新建的，我这里采用默认的<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-38-34.png"></p><p>创建虚拟硬盘，大小按你需求设置<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-39-24.png"></p><p>选择你下载的CentOS<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-40-59.png"></p><p>点击完成<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/image.png"></p><h2 id="启动系统"><a href="#启动系统" class="headerlink" title="启动系统"></a>启动系统</h2><p>连接虚拟机<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-42-41.png"></p><p>直接回车<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-43-07.png"></p><p>选择中文简体<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-44-45.png"></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-47-40.png"><br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-48-09.png"><br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-48-54.png"></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-49-22.png"></p><p>点击开始安装</p><p>设置root用户密码<br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-50-18.png"><br><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-50-54.png"></p><p>等待安装完成</p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-53-30.png"></p><p>重启以后，输入账号密码</p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-54-52.png"></p><h2 id="测试网络"><a href="#测试网络" class="headerlink" title="测试网络"></a>测试网络</h2><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-57-54.png"></p><p><img src="/2022/09/08/%E4%BD%BF%E7%94%A8Windows%E5%86%85%E7%BD%AE%E8%99%9A%E6%8B%9F%E6%9C%BAHyper-v%E5%AE%89%E8%A3%85CentOS/2022-09-08-15-58-25.png"></p><h2 id="其他问题"><a href="#其他问题" class="headerlink" title="其他问题"></a>其他问题</h2><h3 id="Hyper-V：无法打开虚拟机XXX，因为虚拟机监控程序未运行"><a href="#Hyper-V：无法打开虚拟机XXX，因为虚拟机监控程序未运行" class="headerlink" title="Hyper-V：无法打开虚拟机XXX，因为虚拟机监控程序未运行"></a>Hyper-V：无法打开虚拟机XXX，因为虚拟机监控程序未运行</h3><p><a href="https://zhuanlan.zhihu.com/p/20408480">https://zhuanlan.zhihu.com/p/20408480</a></p><p><a href="https://www.jianshu.com/p/624093c28051">https://www.jianshu.com/p/624093c28051</a></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><blockquote><p><a href="https://blog.csdn.net/qq_36077437/article/details/123980445">https://blog.csdn.net/qq_36077437/article/details/123980445</a></p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;下载Centos&quot;&gt;&lt;a href=&quot;#下载Centos&quot; class=&quot;headerlink&quot; title=&quot;下载Centos&quot;&gt;&lt;/a&gt;下载Centos&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;http://mirrors.aliyun.com/centos/7/is</summary>
      
    
    
    
    <category term="虚拟机" scheme="https://www.songhaozhi.com/categories/%E8%99%9A%E6%8B%9F%E6%9C%BA/"/>
    
    
    <category term="虚拟机" scheme="https://www.songhaozhi.com/tags/%E8%99%9A%E6%8B%9F%E6%9C%BA/"/>
    
  </entry>
  
  <entry>
    <title>ruoyi-vue项目集成flyway实现自动创建表</title>
    <link href="https://www.songhaozhi.com/2022/09/08/ruoyi-vue%E9%A1%B9%E7%9B%AE%E9%9B%86%E6%88%90flyway%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E8%A1%A8/"/>
    <id>https://www.songhaozhi.com/2022/09/08/ruoyi-vue%E9%A1%B9%E7%9B%AE%E9%9B%86%E6%88%90flyway%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E8%A1%A8/</id>
    <published>2022-09-08T05:39:19.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="添加flyway依赖"><a href="#添加flyway依赖" class="headerlink" title="添加flyway依赖"></a>添加flyway依赖</h2><p>在根目录下<code>pom.xml</code>添加flyway依赖<code>RuoYi-Vue\pom.xml</code></p><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></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.flywaydb<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>flyway-core<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>7.15.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure><p>在<code>ruoyi-framework\pom.xml</code>下引入</p><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></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.flywaydb<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>flyway-core<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></table></figure><h2 id="yaml配置"><a href="#yaml配置" class="headerlink" title="yaml配置"></a>yaml配置</h2><p>在<code>RuoYi-Vue\ruoyi-admin\src\main\resources\application.yml</code>中添加以下配置</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><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><code class="hljs yaml"><span class="hljs-comment"># 配置flyway数据版本管理</span><br>  <span class="hljs-attr">flyway:</span><br>    <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span><br>    <span class="hljs-attr">baseline-on-migrate:</span> <span class="hljs-literal">true</span><br>    <span class="hljs-attr">clean-on-validation-error:</span> <span class="hljs-literal">false</span><br>    <span class="hljs-attr">sql-migration-prefix:</span> <span class="hljs-string">V</span><br>    <span class="hljs-attr">sql-migration-suffixes:</span> <span class="hljs-string">.sql</span><br>    <span class="hljs-attr">locations:</span> <span class="hljs-string">classpath:db/migration</span><br></code></pre></td></tr></table></figure><div class="note note-info">            <p>flyway.baseline-description对执行迁移时基准版本的描述.<br>flyway.baseline-on-migrate当迁移时发现目标schema非空，而且带有没有元数据的表时，是否自动执行基准迁移，默认false.<br>flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签，默认值为1.<br>flyway.check-location检查迁移脚本的位置是否存在，默认false.<br>flyway.clean-on-validation-error当发现校验错误时是否自动调用clean，默认false.<br>flyway.enabled是否开启flywary，默认true.<br>flyway.encoding设置迁移时的编码，默认UTF-8.<br>flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移，默认false.<br>flyway.init-sqls当初始化好连接时要执行的SQL.<br>flyway.locations迁移脚本的位置，默认db&#x2F;migration.<br>flyway.out-of-order是否允许无序的迁移，默认false.<br>flyway.password目标数据库的密码.<br>flyway.placeholder-prefix设置每个placeholder的前缀，默认${.<br>flyway.placeholder-replacementplaceholders是否要被替换，默认true.<br>flyway.placeholder-suffix设置每个placeholder的后缀，默认}.<br>flyway.placeholders.[placeholder name]设置placeholder的value<br>flyway.schemas设定需要flywary迁移的schema，大小写敏感，默认为连接默认的schema.<br>flyway.sql-migration-prefix迁移文件的前缀，默认为V.<br>flyway.sql-migration-separator迁移脚本的文件名分隔符，默认__<br>flyway.sql-migration-suffix迁移脚本的后缀，默认为.sql<br>flyway.tableflyway使用的元数据表名，默认为schema_version<br>flyway.target迁移时使用的目标版本，默认为latest version<br>flyway.url迁移时使用的JDBC URL，如果没有指定的话，将使用配置的主数据源<br>flyway.user迁移数据库的用户名<br>flyway.validate-on-migrate迁移时是否校验，默认为true.</p>          </div><h2 id="创建目录"><a href="#创建目录" class="headerlink" title="创建目录"></a>创建目录</h2><p>在<code>RuoYi-Vue\ruoyi-system\src\main\resources</code>目录下创建<code>db/migration</code>目录，把若依若依提供的表结构sql文件复制到该文件夹，并且重命名。</p><p>文件命名规则：</p><ul><li><p>仅需要被执行一次的SQL命名以大写的”V”开头，V+版本号(版本号的数字间以”.“或”_“分隔开)+双下划线(用来分隔版本号和描述)+文件描述+后缀名。例如：<code>V20201100__create_user.sql</code>、<code>V2.1.5__create_user_ddl.sql</code>、<code>V4.1_2__add_user_dml.sql</code>。</p></li><li><p>可重复运行的SQL，则以大写的“R”开头，后面再以两个下划线分割，其后跟文件名称，最后以.sql结尾。（不推荐使用）比如：<code>R__truncate_user_dml.sql</code>。</p></li></ul><p> <img src="/2022/09/08/ruoyi-vue%E9%A1%B9%E7%9B%AE%E9%9B%86%E6%88%90flyway%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E8%A1%A8/flyway_create_sql.png"></p><h2 id="若依项目代码修改"><a href="#若依项目代码修改" class="headerlink" title="若依项目代码修改"></a>若依项目代码修改</h2><p>全局搜索一下<code>@PostConstruct</code>,将代码中<code>@PostConstruct</code>注释掉，总共有三个文件需要修改<code>SysJobServiceImpl</code>,<code>SysDictTypeServiceImpl</code>,<code>SysConfigServiceImpl</code></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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 项目启动时，初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理（注：不能手动修改数据库ID和任务组名，否则会导致脏数据）</span><br><span class="hljs-comment"> */</span><br><span class="hljs-comment">//@PostConstruct</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">init</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> SchedulerException, TaskException<br>&#123;<br>    scheduler.clear();<br>    List&lt;SysJob&gt; jobList = jobMapper.selectJobAll();<br>    <span class="hljs-keyword">for</span> (SysJob job : jobList)<br>    &#123;<br>        ScheduleUtils.createScheduleJob(scheduler, job);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><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><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 项目启动时，初始化字典到缓存</span><br><span class="hljs-comment"> */</span><br><span class="hljs-comment">//@PostConstruct</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">init</span><span class="hljs-params">()</span><br>&#123;<br>    loadingDictCache();<br>&#125;<br></code></pre></td></tr></table></figure><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><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 项目启动时，初始化参数到缓存</span><br><span class="hljs-comment"> */</span><br><span class="hljs-comment">//@PostConstruct</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">init</span><span class="hljs-params">()</span><br>&#123;<br>    loadingConfigCache();<br>&#125;<br></code></pre></td></tr></table></figure><p>注释掉以后，我们把启动时初始化的操作移动到<code>RuoYiApplication.java</code>中</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">package</span> com.ruoyi;<br><br><span class="hljs-keyword">import</span> com.ruoyi.quartz.service.impl.SysJobServiceImpl;<br><span class="hljs-keyword">import</span> com.ruoyi.system.service.impl.SysConfigServiceImpl;<br><span class="hljs-keyword">import</span> com.ruoyi.system.service.impl.SysDictTypeServiceImpl;<br><span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;<br><span class="hljs-keyword">import</span> org.springframework.boot.CommandLineRunner;<br><span class="hljs-keyword">import</span> org.springframework.boot.SpringApplication;<br><span class="hljs-keyword">import</span> org.springframework.boot.autoconfigure.SpringBootApplication;<br><span class="hljs-keyword">import</span> org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 启动程序</span><br><span class="hljs-comment"> *</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author</span> ruoyi</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@SpringBootApplication(exclude = &#123; DataSourceAutoConfiguration.class &#125;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RuoYiApplication</span><br>        <span class="hljs-keyword">implements</span> <span class="hljs-title class_">CommandLineRunner</span> &#123;<br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> SysConfigServiceImpl configService;<br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> SysJobServiceImpl jobService;<br>    <span class="hljs-meta">@Autowired</span><br>    <span class="hljs-keyword">private</span> SysDictTypeServiceImpl dictTypeService;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span><br>    &#123;<br>        <span class="hljs-comment">// System.setProperty(&quot;spring.devtools.restart.enabled&quot;, &quot;false&quot;);</span><br>        SpringApplication.run(RuoYiApplication.class, args);<br>        System.out.println(<span class="hljs-string">&quot;(♥◠‿◠)ﾉﾞ  若依启动成功   ლ(´ڡ`ლ)ﾞ  \n&quot;</span> +<br>                <span class="hljs-string">&quot; .-------.       ____     __        \n&quot;</span> +<br>                <span class="hljs-string">&quot; |  _ _   \\      \\   \\   /  /    \n&quot;</span> +<br>                <span class="hljs-string">&quot; | ( &#x27; )  |       \\  _. /  &#x27;       \n&quot;</span> +<br>                <span class="hljs-string">&quot; |(_ o _) /        _( )_ .&#x27;         \n&quot;</span> +<br>                <span class="hljs-string">&quot; | (_,_).&#x27; __  ___(_ o _)&#x27;          \n&quot;</span> +<br>                <span class="hljs-string">&quot; |  |\\ \\  |  ||   |(_,_)&#x27;         \n&quot;</span> +<br>                <span class="hljs-string">&quot; |  | \\ `&#x27;   /|   `-&#x27;  /           \n&quot;</span> +<br>                <span class="hljs-string">&quot; |  |  \\    /  \\      /           \n&quot;</span> +<br>                <span class="hljs-string">&quot; &#x27;&#x27;-&#x27;   `&#x27;-&#x27;    `-..-&#x27;              &quot;</span>);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">(String... args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        configService.init();<br>        jobService.init();<br>        dictTypeService.init();<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure><h2 id="启动项目"><a href="#启动项目" class="headerlink" title="启动项目"></a>启动项目</h2><p>代码编写好以后，我们在数据库中创建一个<code>ry-vue</code>的数据库，在<code>RuoYi-Vue\ruoyi-admin\src\main\resources\application.yml</code>下修改数据库连接和数据库密码等信息。</p><p>启动成功以后，我们会看到<code>ry-vue</code>的数据库中表结构已经创建完成。</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><blockquote><p><a href="https://gitee.com/kidKing/ruoyi-docker-flyway">https://gitee.com/kidKing/ruoyi-docker-flyway</a></p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;添加flyway依赖&quot;&gt;&lt;a href=&quot;#添加flyway依赖&quot; class=&quot;headerlink&quot; title=&quot;添加flyway依赖&quot;&gt;&lt;/a&gt;添加flyway依赖&lt;/h2&gt;&lt;p&gt;在根目录下&lt;code&gt;pom.xml&lt;/code&gt;添加flyway依赖&lt;co</summary>
      
    
    
    
    <category term="Java" scheme="https://www.songhaozhi.com/categories/Java/"/>
    
    
    <category term="Java" scheme="https://www.songhaozhi.com/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Docker常用命令记录</title>
    <link href="https://www.songhaozhi.com/2022/09/07/docker%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E8%AE%B0%E5%BD%95/"/>
    <id>https://www.songhaozhi.com/2022/09/07/docker%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E8%AE%B0%E5%BD%95/</id>
    <published>2022-09-07T02:30:36.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<p>本篇文章以安装MySQL数据库为例子，记录Docker常用命令</p><h2 id="安装docker"><a href="#安装docker" class="headerlink" title="安装docker"></a>安装docker</h2><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">yum <span class="hljs-keyword">install</span> docker -y<br></code></pre></td></tr></table></figure><h2 id="docker容器互联"><a href="#docker容器互联" class="headerlink" title="docker容器互联"></a>docker容器互联</h2><h3 id="新建网络"><a href="#新建网络" class="headerlink" title="新建网络"></a>新建网络</h3><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs applescript">docker network create <span class="hljs-keyword">my</span>-net<br></code></pre></td></tr></table></figure><h3 id="列出所有网络"><a href="#列出所有网络" class="headerlink" title="列出所有网络"></a>列出所有网络</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">docker network <span class="hljs-built_in">ls</span><br></code></pre></td></tr></table></figure><h3 id="将容器连接到网络"><a href="#将容器连接到网络" class="headerlink" title="将容器连接到网络"></a>将容器连接到网络</h3><figure class="highlight perl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs perl">docker network <span class="hljs-keyword">connect</span> <span class="hljs-keyword">my</span>-net mysql<br></code></pre></td></tr></table></figure><h3 id="断开容器的网络"><a href="#断开容器的网络" class="headerlink" title="断开容器的网络"></a>断开容器的网络</h3><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs applescript">docker network disconnect <span class="hljs-keyword">my</span>-net mysql<br></code></pre></td></tr></table></figure><h3 id="删除一个或多个网络"><a href="#删除一个或多个网络" class="headerlink" title="删除一个或多个网络"></a>删除一个或多个网络</h3><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata">docker network <span class="hljs-keyword">rm</span> my-<span class="hljs-keyword">net</span><br></code></pre></td></tr></table></figure><h2 id="docker客户端"><a href="#docker客户端" class="headerlink" title="docker客户端"></a>docker客户端</h2><h3 id="容器使用"><a href="#容器使用" class="headerlink" title="容器使用"></a>容器使用</h3><h4 id="搜索镜像"><a href="#搜索镜像" class="headerlink" title="搜索镜像"></a>搜索镜像</h4><p>这里我们搜索<code>mysql</code>镜像</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">docker search mysql</span><br></code></pre></td></tr></table></figure><h4 id="获取MySQL镜像"><a href="#获取MySQL镜像" class="headerlink" title="获取MySQL镜像"></a>获取<code>MySQL</code>镜像</h4><p>下载需要的版本<code>docker pull mysql:tag</code> </p><p><code>tag</code>代表版本号，没有代表是<code>lastest</code>的</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">docker</span> pull docker.io/mysql:<span class="hljs-number">5</span>.<span class="hljs-number">7</span>.<span class="hljs-number">26</span><br></code></pre></td></tr></table></figure><h4 id="列出本地镜像"><a href="#列出本地镜像" class="headerlink" title="列出本地镜像"></a>列出本地镜像</h4><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs inform7">docker images <span class="hljs-comment">[OPTIONS]</span> <span class="hljs-comment">[REPOSITORY<span class="hljs-comment">[:TAG]</span>]</span><br></code></pre></td></tr></table></figure><div class="note note-info">            <p><strong>OPTIONS说明</strong></p><ul><li><p>-a :列出本地所有的镜像（含中间映像层，默认情况下，过滤掉中间映像层）；</p></li><li><p>–digests :显示镜像的摘要信息；</p></li><li><p>-f :显示满足条件的镜像；</p></li><li><p>–format :指定返回值的模板文件；</p></li><li><p>–no-trunc :显示完整的镜像信息；</p></li><li><p>-q :只显示镜像ID。</p></li></ul>          </div><h4 id="创建-MySQL-数据目录"><a href="#创建-MySQL-数据目录" class="headerlink" title="创建 MySQL 数据目录"></a>创建 MySQL 数据目录</h4><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">mkdir -p <span class="hljs-regexp">/opt/my</span>sql<br></code></pre></td></tr></table></figure><h3 id="启动MySQL实例"><a href="#启动MySQL实例" class="headerlink" title="启动MySQL实例"></a>启动<code>MySQL</code>实例</h3><figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gradle">docker run --name mysql -p <span class="hljs-number">3306</span>:<span class="hljs-number">3306</span> --privileged=<span class="hljs-keyword">true</span> -v <span class="hljs-regexp">/opt/my</span>sql<span class="hljs-regexp">/log:/</span>var<span class="hljs-regexp">/log/my</span>sql -v <span class="hljs-regexp">/opt/my</span>sql<span class="hljs-regexp">/conf:/</span>etc<span class="hljs-regexp">/mysql -v /</span>opt<span class="hljs-regexp">/mysql/</span>data:<span class="hljs-regexp">/var/</span>lib/mysql -e MYSQL_ROOT_PASSWORD=<span class="hljs-number">123456</span> --net my-net --restart=unless-stopped -d mysql:<span class="hljs-number">5.7</span>.<span class="hljs-number">26</span><br></code></pre></td></tr></table></figure><div class="note note-info">            <p><strong>Tips</strong></p><ul><li><p><code>-e MYSQL_ROOT_PASSWORD=123456</code>命令: 指定MySQL的登录密码为 <code>123456</code></p></li><li><p><code>-v /opt/mysql/data:/var/lib/mysql</code> 命令: 将宿主机的目录 <code>/opt/mysql</code> 挂载到容器内部的目录 <code>/var/lib/mysql</code>，默认情况下 <code>MySQL</code> 将向 <code>/opt/mysql</code> 写入其数据文件。</p></li><li><p><code>-v /opt/mysql/conf:/etc/mysql</code>命令：MySQL配置文件存放位置</p></li><li><p><code> -v /opt/mysql/log:/var/log/mysql</code>命令：MySQL日志文件</p></li><li><p><code>--net my-net</code>命令: 将该容器加入到 <code>my-net</code> 网络,连接到 <code>my-net</code> 网络的任何其他容器都可以访问 <code>mysql</code> 容器上的所有端口。</p></li><li><p><code>--restart=unless-stopped</code>命令：在容器退出时总是重启容器，但是不考虑在Docker守护进程启动时就已经停止了的容器 </p></li><li><p><code>-d</code>命令：表示后台运行</p></li><li><p><code>-p 3306:3306</code>命令：端口映射</p></li><li><p><code>--privileged=true</code>命令：container内的root拥有真正的root权限</p></li></ul>          </div><h3 id="查看docker容器运行情况"><a href="#查看docker容器运行情况" class="headerlink" title="查看docker容器运行情况"></a>查看docker容器运行情况</h3><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">docker ps</span><br></code></pre></td></tr></table></figure><h3 id="查看所有的容器"><a href="#查看所有的容器" class="headerlink" title="查看所有的容器"></a>查看所有的容器</h3><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">docker ps -<span class="hljs-selector-tag">a</span><br></code></pre></td></tr></table></figure><h3 id="启动一个已停止的容器"><a href="#启动一个已停止的容器" class="headerlink" title="启动一个已停止的容器"></a>启动一个已停止的容器</h3><figure class="highlight xquery"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xquery">docker <span class="hljs-keyword">start</span> 容<span class="hljs-built_in">器id</span><br></code></pre></td></tr></table></figure><h3 id="停止一个容器"><a href="#停止一个容器" class="headerlink" title="停止一个容器"></a>停止一个容器</h3><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arduino">docker stop &lt;容器 ID&gt;<br></code></pre></td></tr></table></figure><p>停止的容器可以通过 docker restart 重启：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml">docker restart <span class="hljs-tag">&lt;<span class="hljs-name">容器</span> <span class="hljs-attr">ID</span>&gt;</span><br></code></pre></td></tr></table></figure><h3 id="进入MySQL容器"><a href="#进入MySQL容器" class="headerlink" title="进入MySQL容器"></a>进入MySQL容器</h3><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">docker exec -it mysql <span class="hljs-regexp">/bin/</span>bash<br></code></pre></td></tr></table></figure><div class="note note-info">            <p><strong>Tips</strong></p><ul><li>-i: 交互式操作。</li><li>-t: 终端。</li><li>mysql: mysql 镜像。</li><li>&#x2F;bin&#x2F;bash：放在镜像名后的是命令，这里我们希望有个交互式 Shell，因此用的是 &#x2F;bin&#x2F;bash。</li></ul>          </div><h3 id="退出容器"><a href="#退出容器" class="headerlink" title="退出容器"></a>退出容器</h3><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk"><span class="hljs-keyword">exit</span><br></code></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><blockquote><p><a href="https://www.runoob.com/docker/docker-tutorial.html">https://www.runoob.com/docker/docker-tutorial.html</a></p></blockquote><blockquote><p><a href="https://docs.halo.run/getting-started/install/other/docker-mysql">https://docs.halo.run/getting-started/install/other/docker-mysql</a></p></blockquote><blockquote><p><a href="https://www.yiibai.com/docker/docker-introduction.html">https://www.yiibai.com/docker/docker-introduction.html</a></p></blockquote><blockquote><p><a href="https://www.jianshu.com/p/68ec752f0454">https://www.jianshu.com/p/68ec752f0454</a></p></blockquote>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;本篇文章以安装MySQL数据库为例子，记录Docker常用命令&lt;/p&gt;
&lt;h2 id=&quot;安装docker&quot;&gt;&lt;a href=&quot;#安装docker&quot; class=&quot;headerlink&quot; title=&quot;安装docker&quot;&gt;&lt;/a&gt;安装docker&lt;/h2&gt;&lt;figure cl</summary>
      
    
    
    
    <category term="Docker" scheme="https://www.songhaozhi.com/categories/Docker/"/>
    
    
    <category term="Docker" scheme="https://www.songhaozhi.com/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>vue学习笔记四-列表渲染</title>
    <link href="https://www.songhaozhi.com/2022/09/05/vue%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E5%9B%9B-%E5%88%97%E8%A1%A8%E6%B8%B2%E6%9F%93/"/>
    <id>https://www.songhaozhi.com/2022/09/05/vue%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E5%9B%9B-%E5%88%97%E8%A1%A8%E6%B8%B2%E6%9F%93/</id>
    <published>2022-09-05T07:21:55.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="v-for"><a href="#v-for" class="headerlink" title="v-for"></a><code>v-for</code></h2><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;template&gt;<br> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;user in userList&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;user.id&quot;</span>&gt;</span>id:&#123;&#123; user.id &#125;&#125;  name:&#123;&#123; user.name &#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml"> <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br>&lt;/template&gt;<br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;list&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">      <span class="hljs-attr">userList</span>: [</span></span><br><span class="language-javascript"><span class="language-xml">        &#123; <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;1&quot;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span> &#125;,</span></span><br><span class="language-javascript"><span class="language-xml">        &#123; <span class="hljs-attr">id</span>: <span class="hljs-string">&quot;2&quot;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;李四&quot;</span> &#125;,</span></span><br><span class="language-javascript"><span class="language-xml">      ],</span></span><br><span class="language-javascript"><span class="language-xml">    &#125;;</span></span><br><span class="language-javascript"><span class="language-xml">  &#125;,</span></span><br><span class="language-javascript"><span class="language-xml">&#125;;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure><h2 id="维护状态"><a href="#维护状态" class="headerlink" title="维护状态"></a>维护状态</h2><p>当Vue正在更新使用<code>v-for</code>渲染的元素列表时，它默认使用“就地更新的策略。如果数据项的顺序被改变，Vue将不会移动DOM元素来匹配数据项的顺序，而是就地更新每个元素，并且确保它们在每个索引的位置正确渲染。</p><p>为了给Vue一个提示，以便它能跟踪每个节点的身份，从而重用和重新排序现有元素，你需要为每项提供一个唯一的<code>key</code>attribute</p><figure class="highlight javascript"><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><code class="hljs JavaScript"><br>&lt;li v-<span class="hljs-keyword">for</span>=<span class="hljs-string">&quot;user in userList&quot;</span> :key=<span class="hljs-string">&quot;user.id&quot;</span>&gt;<span class="hljs-attr">id</span>:&#123;&#123; user.<span class="hljs-property">id</span> &#125;&#125;  <span class="hljs-attr">name</span>:&#123;&#123; user.<span class="hljs-property">name</span> &#125;&#125;&lt;/li&gt;<br><br></code></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;v-for&quot;&gt;&lt;a href=&quot;#v-for&quot; class=&quot;headerlink&quot; title=&quot;v-for&quot;&gt;&lt;/a&gt;&lt;code&gt;v-for&lt;/code&gt;&lt;/h2&gt;&lt;figure class=&quot;highlight javascript&quot;&gt;&lt;table&gt;&lt;tr&gt;</summary>
      
    
    
    
    <category term="Web前端" scheme="https://www.songhaozhi.com/categories/Web%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://www.songhaozhi.com/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>vue学习笔记三条件渲染</title>
    <link href="https://www.songhaozhi.com/2022/09/02/conditional/"/>
    <id>https://www.songhaozhi.com/2022/09/02/conditional/</id>
    <published>2022-09-02T10:25:03.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="v-if"><a href="#v-if" class="headerlink" title="v-if"></a><code>v-if</code></h2><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;template&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;flag&quot;</span>&gt;</span>真<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><br>&lt;/template&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;conditional&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">      <span class="hljs-attr">flag</span>: <span class="hljs-literal">true</span></span></span><br><span class="language-javascript"><span class="language-xml">    &#125;;</span></span><br><span class="language-javascript"><span class="language-xml">  &#125;,</span></span><br><span class="language-javascript"><span class="language-xml">&#125;;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure><h2 id="v-else"><a href="#v-else" class="headerlink" title="v-else"></a><code>v-else</code></h2><figure class="highlight javascript"><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><code class="hljs JavaScript"><br>&lt;template&gt;<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;flag = !flag&quot;</span>&gt;</span>改变<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;flag&quot;</span>&gt;</span>真<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-else</span>&gt;</span>假<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><br>&lt;/template&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;conditional&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">      <span class="hljs-attr">flag</span>: <span class="hljs-literal">true</span></span></span><br><span class="language-javascript"><span class="language-xml">    &#125;;</span></span><br><span class="language-javascript"><span class="language-xml">  &#125;,</span></span><br><span class="language-javascript"><span class="language-xml">&#125;;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure><h3 id="v-else-if"><a href="#v-else-if" class="headerlink" title="v-else-if"></a><code>v-else-if</code></h3><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;template&gt;<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;type === &#x27;A&#x27;&quot;</span>&gt;</span>A<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-else-if</span>=<span class="hljs-string">&quot;type === &#x27;B&#x27;&quot;</span>&gt;</span>B<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-else-if</span>=<span class="hljs-string">&quot;type === &#x27;C&#x27;&quot;</span>&gt;</span>C<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-else</span>&gt;</span>不存在<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&lt;/template&gt;<br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;conditional&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">      <span class="hljs-attr">type</span>:<span class="hljs-string">&#x27;A&#x27;</span></span></span><br><span class="language-javascript"><span class="language-xml">    &#125;;</span></span><br><span class="language-javascript"><span class="language-xml">  &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;;</span></span><br><span class="language-javascript"><span class="language-xml"></span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br><br></code></pre></td></tr></table></figure><h2 id="v-show"><a href="#v-show" class="headerlink" title="v-show"></a><code>v-show</code></h2><p>另一个可以用来按条件显示一个元素的指令是 <code>v-show</code>。其用法基本一样：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs JavaScript">&lt;h1 v-show=<span class="hljs-string">&quot;flag&quot;</span>&gt;<span class="hljs-title class_">Hello</span>!&lt;/h1&gt;<br></code></pre></td></tr></table></figure><p>不同之处在于 <code>v-show</code> 会在 DOM 渲染中保留该元素；<code>v-show</code> 仅切换了该元素上名为 <code>display</code> 的 CSS 属性。</p><p><code>v-show</code> 不支持在 <code>&lt;template&gt;</code> 元素上使用，也不能和 <code>v-else</code> 搭配使用</p><h2 id="v-if-vs-v-show"><a href="#v-if-vs-v-show" class="headerlink" title="v-if vs v-show"></a><code>v-if</code> vs <code>v-show</code></h2><p><code>v-if</code> 是“真实的”按条件渲染，因为它确保了在切换时，条件区块内的事件监听器和子组件都会被销毁与重建。</p><p><code>v-if</code> 也是<strong>惰性</strong>的：如果在初次渲染时条件值为 false，则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。</p><p>相比之下，<code>v-show</code> 简单许多，元素无论初始条件如何，始终会被渲染，只有 CSS <code>display</code> 属性会被切换。</p><p>总的来说，<code>v-if</code> 有更高的切换开销，而 <code>v-show</code> 有更高的初始渲染开销。因此，如果需要频繁切换，则使用 <code>v-show</code> 较好；如果在运行时绑定条件很少改变，则 <code>v-if</code> 会更合适。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;v-if&quot;&gt;&lt;a href=&quot;#v-if&quot; class=&quot;headerlink&quot; title=&quot;v-if&quot;&gt;&lt;/a&gt;&lt;code&gt;v-if&lt;/code&gt;&lt;/h2&gt;&lt;figure class=&quot;highlight javascript&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td </summary>
      
    
    
    
    <category term="Web前端" scheme="https://www.songhaozhi.com/categories/Web%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://www.songhaozhi.com/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>vue学习笔记二模板语法</title>
    <link href="https://www.songhaozhi.com/2022/09/02/template-syntax/"/>
    <id>https://www.songhaozhi.com/2022/09/02/template-syntax/</id>
    <published>2022-09-02T10:23:45.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="文本插值"><a href="#文本插值" class="headerlink" title="文本插值"></a>文本插值</h2><p>最基本的数据绑定形式是文本插值，它使用的是“Mustache”语法 (即双大括号)：</p><figure class="highlight handlebars"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs handlebars"><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Message: </span><span class="hljs-template-variable">&#123;&#123; <span class="hljs-name">msg</span> &#125;&#125;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><br></code></pre></td></tr></table></figure><p>双大括号标签会被替换为相应组件实例中 <code>msg</code> 属性的值。同时每次 <code>msg</code> 属性更改时它也会同步更新                                               。</p><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;template&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span> Message：&#123;&#123;msg&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><br>&lt;/template&gt;<br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-attr">name</span>:<span class="hljs-string">&quot;text&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span>&#123;</span></span><br><span class="language-javascript"><span class="language-xml">        <span class="hljs-attr">msg</span>:<span class="hljs-string">&quot;消息提醒&quot;</span></span></span><br><span class="language-javascript"><span class="language-xml">    &#125;</span></span><br><span class="language-javascript"><span class="language-xml">  &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure><h2 id="原始-HTML"><a href="#原始-HTML" class="headerlink" title="原始 HTML"></a>原始 HTML</h2><p>双大括号将会将数据插值为纯文本，而不是 HTML。若想插入 HTML，你需要使用 <a href="https://cn.vuejs.org/api/built-in-directives.html#v-html"><code>v-html</code> 指令</a>：</p><figure class="highlight javascript"><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><code class="hljs JavaScript"><br>&lt;template&gt;<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>插值方式：&#123;&#123;rawHtml&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> &gt;</span>HTML方式:<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-html</span>=<span class="hljs-string">&quot;rawHtml&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&lt;/template&gt;<br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>&#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-attr">name</span>:<span class="hljs-string">&quot;RawHtml&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>)&#123;</span></span><br><span class="language-javascript"><span class="language-xml">        <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">        <span class="hljs-attr">rawHtml</span>:<span class="hljs-string">&quot;&lt;a href=&#x27;http://www.baidu.com&#x27;&gt;百度&lt;/a&gt;&quot;</span></span></span><br><span class="language-javascript"><span class="language-xml">    &#125;</span></span><br><span class="language-javascript"><span class="language-xml">   &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure><h2 id="Attribute-绑定"><a href="#Attribute-绑定" class="headerlink" title="Attribute 绑定"></a>Attribute 绑定</h2><p>双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute，应该使用 <a href="https://cn.vuejs.org/api/built-in-directives.html#v-bind"><code>v-bind</code> 指令</a>：</p><div v-bind:id="dynamicId"></div><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-bind:id</span>=<span class="hljs-string">&quot;dynamicId&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure><p><code>v-bind</code> 指令指示 Vue 将元素的 <code>id</code> attribute 与组件的 <code>dynamicId</code> 属性保持一致。如果绑定的值是 <code>null</code> 或者 <code>undefined</code>，那么该 attribute 将会从渲染的元素上移除。</p><h3 id="简写"><a href="#简写" class="headerlink" title="简写"></a>简写</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">:id</span>=<span class="hljs-string">&quot;dynamicId&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure><p>开头为 <code>:</code> 的 attribute 可能和一般的 HTML attribute 看起来不太一样，但它的确是合法的 attribute 名称字符，并且所有支持 Vue 的浏览器都能正确解析它。此外，他们不会出现在最终渲染的 DOM 中</p><h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight javascript"><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><code class="hljs JavaScript"><br>&lt;template&gt;<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-bind:id</span>=<span class="hljs-string">&quot;dynamicId&quot;</span>&gt;</span></span><br><span class="language-xml">        Attribute 绑定ID</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">:id</span>=<span class="hljs-string">&quot;dynamicId&quot;</span>&gt;</span></span><br><span class="language-xml">        Attribute 绑定ID 简写</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&lt;/template&gt;<br>  <br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;attributeBindings&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">        <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">            <span class="hljs-attr">dynamicId</span>: <span class="hljs-string">&quot;10001&quot;</span></span></span><br><span class="language-javascript"><span class="language-xml">        &#125;</span></span><br><span class="language-javascript"><span class="language-xml">    &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br><br></code></pre></td></tr></table></figure><h2 id="使用-JavaScript-表达式"><a href="#使用-JavaScript-表达式" class="headerlink" title="使用 JavaScript 表达式"></a>使用 JavaScript 表达式</h2><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;template&gt;<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&#123;&#123;number +1&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>isok:&#123;&#123;ok ? &#x27;YES&#x27;:&#x27;NO&#x27; &#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>message:&#123;&#123;message.split(&#x27;&#x27;).reverse().join(&#x27;&#x27;)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&lt;/template&gt;<br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;JavaScript&quot;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-title function_">data</span>(<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">        <span class="hljs-keyword">return</span> &#123;</span></span><br><span class="language-javascript"><span class="language-xml">            <span class="hljs-attr">number</span>:<span class="hljs-number">10</span>,</span></span><br><span class="language-javascript"><span class="language-xml">            <span class="hljs-attr">ok</span>:<span class="hljs-string">&#x27;YES&#x27;</span>,</span></span><br><span class="language-javascript"><span class="language-xml">            <span class="hljs-attr">message</span>:<span class="hljs-string">&#x27;Hello&#x27;</span></span></span><br><span class="language-javascript"><span class="language-xml">        &#125;</span></span><br><span class="language-javascript"><span class="language-xml">    &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br><br></code></pre></td></tr></table></figure><p>这些表达式会在当前活动实例的数据作用域下作为JavaScript被解析。有个限制就是，每个绑定都只能包含<strong>单个表达式</strong>，所以下面的例子都<strong>不会</strong>生效。</p><figure class="highlight javascript"><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><code class="hljs JavaScript">&lt;!-- 这是语句，不是表达式--&gt;<br>&#123;&#123; <span class="hljs-keyword">var</span> a = <span class="hljs-number">1</span> &#125;&#125;<br><br>&lt;!--流程控制也不会生效，请使用三元表达式--&gt;<br>&#123;&#123;<span class="hljs-keyword">if</span>(ok) &#123; <span class="hljs-keyword">return</span> message &#125;&#125;&#125;<br><br></code></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;文本插值&quot;&gt;&lt;a href=&quot;#文本插值&quot; class=&quot;headerlink&quot; title=&quot;文本插值&quot;&gt;&lt;/a&gt;文本插值&lt;/h2&gt;&lt;p&gt;最基本的数据绑定形式是文本插值，它使用的是“Mustache”语法 (即双大括号)：&lt;/p&gt;
&lt;figure class=&quot;</summary>
      
    
    
    
    <category term="Web前端" scheme="https://www.songhaozhi.com/categories/Web%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://www.songhaozhi.com/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>vue学习笔记一创建项目</title>
    <link href="https://www.songhaozhi.com/2022/09/02/create-vue-project/"/>
    <id>https://www.songhaozhi.com/2022/09/02/create-vue-project/</id>
    <published>2022-09-02T10:08:13.000Z</published>
    <updated>2022-11-14T07:57:13.752Z</updated>
    
    <content type="html"><![CDATA[<h2 id="创建项目"><a href="#创建项目" class="headerlink" title="创建项目"></a>创建项目</h2><p>1.采用Vite 驱动的 Vue 项目</p><p> <img src="/2022/09/02/create-vue-project/20220902114652.png"></p><p>2.启动项目</p><p> <img src="/2022/09/02/create-vue-project/20220902114829.png"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;创建项目&quot;&gt;&lt;a href=&quot;#创建项目&quot; class=&quot;headerlink&quot; title=&quot;创建项目&quot;&gt;&lt;/a&gt;创建项目&lt;/h2&gt;&lt;p&gt;1.采用Vite 驱动的 Vue 项目&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;/2022/09/02/create-vue-p</summary>
      
    
    
    
    <category term="Web前端" scheme="https://www.songhaozhi.com/categories/Web%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://www.songhaozhi.com/tags/Vue/"/>
    
  </entry>
  
</feed>
