标签: 随笔

  • 读《中美相遇:大国外交与晚清兴衰(1784-1911)(美国人为何选择贸易战?美国妖魔化中国的源头在哪里?解读今日中美关系。)》

    读《中美相遇:大国外交与晚清兴衰(1784-1911)(美国人为何选择贸易战?美国妖魔化中国的源头在哪里?解读今日中美关系。)》

    读完了。中美近几年摩擦不断,从新闻报道上,感到美国正在从各个方面不择手段地围堵中国,很想知道是为什么,这本书好像能找到答案。

    在读这本书之前,了解到的一些原因可能包括:

    1. 美国要维护自己世界第一的位置
    2. 美国不希望一个社会主义国家崛起
    3. 中国的发展,抢了美国的生意
    4. 担心中国强大后会发动战争,美国作为“世界警察”要维护和平
    5. ……

    来华

    自古(比哥伦布、麦哲伦还古的古)以来,西方都称东方为神秘的东方,想象中的东方是生机盎然、富丽堂皇的,那时候的中国也确实是生机盎然、富丽堂皇的。周边的国家以天朝为榜样,作天朝的附属国,来华朝贡,在朝廷的许可下做生意。这个时期的天朝自然以为自己是世界的中心,皇帝是天下人的皇帝。

    西方通过工业革命快速迈入近代化,航海事业的发展终于让大量的西方人得以目睹天朝的风范…… 然而看到的却是一个虽依然富饶美丽,但在科技、军事等领域已极大的落后于世界而不自知的古国面貌。巨龙深卧潭底太久,膘肥体胖,已经不能起舞。

    第二次来做客的西方人,带来了他们的坚船利炮,撬开了古国的大门。在这些西方国家中,美国相比于其他国家,与中国的往来,表现上要好很多。彼时的中国,感到了自己的落后,也希望能融入新的诞生于欧美的世界文明体系中,但同时也不想失去天朝的尊严。欧洲来的洋人,整体表现上充满了对中国的蔑视。美国来的洋人,行事风格较为温和,也乐意帮助中国走出去看外面的世界,整体而言是平等友善的,这或许也与来华主事的人有关系。

    其中最著名的一个人是蒲安臣,曾发表过《勿扰她》演讲。他向世界介绍了中国的历史成就,中国曾经是个伟大的国家,只不过近来落后了。他呼吁欧美国家不要打扰中国,中国有自己的发展节奏。

    这或许与欧美各国不同的对华政策有关。一方希望通过枪炮彻底摧毁中国,然后以欧美的方式重塑中国,另一方希望缓慢友好地以外交、贸易、宗教等手段把中国变成一个西方国家。

    慈禧

    后来,来华的所有西方列强都加入了瓜分中国的战争中。从书中了解到了慈禧的另一面,也对义和团有了新的认识。义和团打着“扶清灭洋”的旗号直接攻击了西方驻京使馆区,清廷也出兵助力,这直接引发了八国联军侵华战争。而在此之前,慈禧刚刚首次邀请驻京大使的夫人们到宫廷,宴请送礼,友好交谈,试图以“夫人外交”的方式缓和与西方列强的关系,可义和团攻击使馆区的行为让慈禧的努力化为乌有。《辛丑条约》后,慈禧又做了一系列的外交努力,这改变了我以往对慈禧“丑恶的老太婆”的形象认知。

    大概慈禧终结了“维新”运动错误太大,使后来的人们对她深恶痛绝吧。书中提到康有为维新变法,但是从始至终是坚定的“保皇派”,而梁启超就对保有皇帝没有感觉,原因是康有为被皇帝召见过,梁启超没有。所有“面圣”过的人,几乎都会臣服于皇帝。西方驻京使者的夫人在受到慈禧召见后,也对慈禧赞不绝口,甚至评价为一生中的高光时刻。可见“帝王之术“对人心理的巨大作用力,皇帝可称之为最高端的 PUA 玩家。

    朝鲜

    我的认知里,朝鲜是一个和中国一样地位的国家,历史上包括韩国在内的整个朝鲜半岛都是中国的附属国,现在对此有了更深的理解。附属国(下国)实际上的意义在于遭到侵袭时,宗主国(上国)是不是可以合法出兵保护。此外,下国需要向上国朝贡,在军事、外交、政策上受上国制约,在礼仪上要显示低一等的地位,但是下国有自己的领土主权,有自己的经济发展自主权等,在国际交往上形同于宗主国一样的主权国家。现在似乎只是没了朝贡一说,从这里看,现在的朝鲜与中国的关系也还是基本未变的,而日本、韩国的国际地位与朝鲜也没啥不同,上国不同而已。

    文明

    西方的文明和中国的文明存在着一些不同,中国的文明给了中国人很高的道德感,名誉甚至比命重要。中国向来说话算数,被人指责后,道德羞耻感很重。中国跟西方相比,“脸皮”很薄。而西方基本上是从利益出发的,利益面前,可以不要脸。

    读完此书,尤其感到美国这个国家,几乎所有的政策、行为都是从利益出发的,真的是非常“单纯”的。大概西方文明国家都是以此为行为准则的吧,其他所有国际规则、条约都无关紧要。甚至,只要拳头硬,谁家的东西他们只要想要,都可以去拿。谁文明谁野蛮,可想而知。

    用书中一句话作为结束语:

    中国这个老大帝国,在周围地域乃至全球范围内,其实都是没有朋友的。

    《中美相遇》
  • openresty 部署 https 并开启 http2 支持

    openresty 部署 https 并开启 http2 支持

    这里分两步介绍,第一部是配置 https , 第二步是开启 http2 支持。事实上开启 http2 支持,必须配置站点使用 https 传输协议。

    HTTPS

    为站点部署开启 HTTPS 支持,需要一个可信任的第三方 SSL 证书,然后针对不同的服务器环境进行配置。

    我选择使用Certbot来部署一个免费、可自动更新的由Let’s Encrypt提供的期限为 90 天的权威可信任证书。Certbot官网根据不同的服务器环境提供了不同的部署方法,我使用 ubuntu + openresty(nginx) ,根据官网介绍部署方式如下:

    1. 安装 certbot(或者通过源码安装certbot
    $ sudo apt-get update
    $ sudo apt-get install python-software-properties software-properties-common
    $ sudo add-apt-repository ppa:certbot/certbot
    $ sudo apt-get update
    $ sudo apt-get install certbot
    
    1. 获得证书
    $ certbot(or path/certbot-auto) certonly --webroot -w /path/your-web-root -d your-domain.com -d www.your-domain.com
    

    执行上述代码后,会在系统的/etc/letsencrypt/live目录下生成以your-domain.com的目录,里面会生成cert.pem``chain.pem``fullchain.pem``privkey.pem``README几个文件接下来在 nginx 配置文件中需要用到fullchain.pem``privkey.pem两个文件,这有关SSL证书链的概念,超出本文叙述范围。
    3. 配置 nginx,在 server 中与 https 相关的配置如下

    server {
       ...
       listen 443 ssl;
       ssl on;
       ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    
       ssl_session_cache shared:le_nginx_SSL:1m;
       ssl_session_timeout 1440m;
    
       ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
       ssl_ciphers RC4:HIGH:!aNULL:!MD5;
       ssl_prefer_server_ciphers on;
       ...
    }
    
    1. 执行nginx -t测试 nginx 配置是否正确,确认无误后,重启 nginx 服务。
    2. 设置证书自动更新。
      上文说过Let’s Encrypt提供的免费证书期限为 90 天,certbot 提供了证书自动更新服务,通过源码安装则需要进行一些配置(配置系统的定时任务)。
      1. (Ubuntu) 在/var/spool/cron/crontabs/root文件中添加以下配置:
      0 0 * * * root /path/certbot-auto renew --quiet --no-self-upgrade
      1. 使用certbot renew --dry-run命令测试是否配置成功。

    HTTP2

    配置好 HTTPS 后开启 HTTP2 比较简单,两步即可完成。

    1. 重新编译openresty加入--with-http_v2_module --with-http_ssl_module选项,替换系统中使用的nginx执行文件:
    ./configure --with-http_v2_module --with-http_ssl_module
    make // 不要 make install
    

    关闭 nginx,使用编译生成的/resources/openresty-1.11.2.2/build/nginx-1.11.2/objs/nginx文件替换系统正使用的/usr/local/openresty/nginx/sbin/nginx文件,重启 nginx 即可。
    2. 修改 nginx 配置。在 listen 后添加 http2 ,如下所示:

    server {
       ...
       listen 443 ssl http2;
       ...
    }
    

    如果一开始就开启了 nginx 的 h2 模块,就不需要第一步了。至此,配置 https 并开启 http2 完成。

  • 树莓派使用 frp 实现内网穿透搭建 Nextcloud 私有云

    树莓派使用 frp 实现内网穿透搭建 Nextcloud 私有云

    在家庭网络没有固定 IP 或者家庭网络不能被外网访问的情况下,使用树莓派搭建 Nextcloud 私有云系统服务,需要借助于有外网 IP 的服务器,使用frp等工具进行内网穿透,整套系统的访问过程示意如下:

    格安云服务示意.png



    如果你直接访问到了这个页面,可参考下《树莓派使用 frp 实现内网穿透搭建 Nextcloud 私有云的准备工作》了解采用此方案搭建 Nextcloud 私有云服务所要进行的准备工作,以便快速上手,少走弯路。

    这里主要介绍使用 frp 进行内网穿透和 Nextcloud 私有云的安装。

    搭建内网穿透服务

    1. 参考Github-frp安装配置好 frp 内网穿透服务;
      我的树莓派端的配置文件关键信息如下:
     [common]
     server_addr = [your-public-server-ip]
     server_port = 7000
     privilege_token = [your-privilege_token]
    
     

    [ssh]

    type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000

    [web]

    privilege_mode = true type = http local_port = 80 custom_domains = [your-domain]

    我的公网服务器端的配置文件关键信息如下:

     [common]
     bind_port = 7000
     vhost_http_port = 8080
     dashboard_port = 7500
     # dashboard 用户名密码,默认都为 admin
     dashboard_user = [your-dashboard_user]
     dashboard_pwd = [your-dashboard_pwd]
     privilege_mode = true
     privilege_token = [your-privilege_token]
     privilege_allow_ports = 4000-50000
     log_file = [path]/frps.log
     log_level = info
     log_max_days = 3
    
    1. 公网服务器端配置 Nginx,转发外网访问请求到 frp server 服务;
    server {
     listen 80;
     server_name  [your-domain];
    
     location / {
        proxy_pass http://127.0.0.1:8080; # frp server 端的 vhost_http_port 配置的端口
        proxy_set_header    Host            $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_hide_header   X-Powered-By;
      }
    }
    
    1. 配置好后,通过域名 [your-domain] 访问树莓派 Nginx 的默认网站测试配置是否正确

    安装 Nextcloud

    1. 解压下载好的 Nextcloud 程序文件到安装准备工作中创建的 web 目录:[path]/web/nextcloud
    2. 设置目录权限
     $ sudo chown -R nobody:nobody [path]/web/nextcloud
    
    1. 参考Nextcloud Nginx Configuration配置 Nginx,推荐使用 socket 方式连接 php-fpm
    upstream php-handler {
     # server 127.0.0.1:9000;
     server unix:/var/run/php71-fpm.sock;
    }
    
    1. 现在可以通过域名 [your-domain] 访问到 Nextcloud 服务了,通过 Nextcloud 的安装向导设置用户名、密码、数据存储路径和数据库信息后,Nextcloud 私有云就搭建好了。如果是严格按照《树莓派结合 frp、Nextcloud 搭建私有云之安装前的准备》进行的前期准备工作,那么:
      • 数据存储路径:[path]/disk
      • 数据库:MariaDB
      • 数据库用户名: nobody
      • 数据库密码:[your-password]
    2. 系统界面。
    屏幕快照 2017-06-29 下午1.41.02副本.png
  • Laravel 使用 Laravel Mix 打包前端静态资源,引入 Vue

    Laravel 使用 Laravel Mix 打包前端静态资源,引入 Vue

    Laravel 的静态资源处理方式不断更新,5.4 版本从 基于 gulp 的 laravel-elixir 完全升级到构建于 webpack 之上的 laravel-mix。

    项目原来的打包策略

    1445238527elixir-1024x549.jpg

    本站基于 Laravel 开发,更新到 Laravel 5.4 之前的静态资源打包混合使用laravel-elixir(gulp)webpack,由于要实现静态资源(主要是 js)跟随版本的模块化加载,以便下一步实现静态资源分离,使用 CDN 加速(本站使用七牛),其时的gulpfile.js打包脚本如下:

    /* ...省略了一些变量定义代码... */
    
    elixir(function (mix) {
        /* bootstrap 字库 */
        mix.copy(AWESOME_FONT_PATH, `${DIST_PATH}/fonts`);
    
        /* 复制图片 */
        mix.copy('resources/assets/img', `${DIST_PATH}/img`);
    
        /* CSS 处理 */
        mix.sass('lib.scss', `${DIST_PATH_WITH_VERSION}/css/lib.css`);
        mix.sass('app.scss', `${DIST_PATH_WITH_VERSION}/css/app.css`);
        mix.sass('control.scss', `${DIST_PATH_WITH_VERSION}/css/control.css`);
    
        /* JS 处理 */
        mix.webpack([], `${DIST_PATH_WITH_VERSION}/js`);
    });
    

    webpack.config.js文件中的处理脚本如下:

    /* ...省略了一些变量定义代码... */
    
    // webpack 入口
    let entry = {
        vendor: ['jquery', 'bootstrap-sass']
    };
    
    /**
     * 生成文件入口
     */
    _.forEach(JS_MODULES, module => {
        if (module !== 'helpers') {
            entry[module] = path.resolve(JS_PATH, module, 'index.js');
        }
    });
    
    //noinspection JSUnresolvedVariable
    module.exports = {
        entry: entry,
        output: {
            filename: '[name].bundle.js'
        },
        resolve: {
            alias: {
                'jquery': path.join(__dirname, 'node_modules/jquery/src/jquery')
            }
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                names: ['vendor', 'manifest'],
            }),
        ],
    };
    

    更新到 Laravel 5.4 之后项目的打包策略

    1-LthzZzfbaat9WPg6hQRCNg.png

    更新到 Laravel 5.4 之后,全部使用 webpack 来打包静态资源,迁移步骤如下:

    1. 参考 Laravel 5.4 更新 package.json 文件;
    2. 添加webpack.mix.js文件;
    3. 复制一份webpack.config.js文件到项目的根目录(备份好原有的配置文件):cp node_modules/laravel-mix/setup/webpack.config.js webpack.config.js 删除package.json文件scripts字段中如下参数配置,以加载使用复制的配置文件--config=node_modules/laravel-mix/setup/webpack.config.js 使用复制的 webpack 配置文件的原因是要支持模块化跟随版本的打包方式,实际上仅仅修改了原有配置中的输出路径。
    4. 迁移原有的配置,webpack.mix.js文件更新如下:const { mix } = require('laravel-mix'); /* ...省略了一些变量定义代码... */ /* CSS 处理 */ mix.sass('resources/assets/sass/lib.scss', `${DIST_PATH_WITH_VERSION}/css/lib.css`) .sass('resources/assets/sass/app.scss', `${DIST_PATH_WITH_VERSION}/css/app.css`) .sass('resources/assets/sass/control.scss', `${DIST_PATH_WITH_VERSION}/css/control.css`); /* JS 处理 */ _.forEach(JS_MODULES, module => { if (module !== 'helpers') { mix.js(`${JS_PATH}/${module}/index.js`, `${DIST_PATH_WITH_VERSION}/js/${module}.bundle.js`); } }); /* Vue 处理 */ mix.js('resources/vue/index.js', `${DIST_PATH_WITH_VERSION}/js/vue.bundle.js`); /* 公共库 */ mix.extract(['jQuery', 'vue'], `${DIST_PATH_WITH_VERSION}/js/vendor.bundle.js`); 可以看到,添加了 Vue 处理路径配置,具体的处理脚本,原作者已经在webpack.config.js中写好了!

    无论是原有的打包方式,还是新的打包方式,,我们要做的也就是根据项目规划,配置一下打包文件入口和输出而已,其他的处理,Laravel 已经配置好了。

  • 树莓派(Raspberry Pi)入门实战记录之 SSH 局域网无线连接

    树莓派(Raspberry Pi)入门实战记录之 SSH 局域网无线连接

    树莓派作为一台完整的微型电脑,可玩性很高。树莓派使用 microSD Card 作为存储介质,安装系统就是把系统镜像写入 microSD Card 中。将写好系统的 microSD Card 放入树莓派的 microSD Card 插槽中,通电,就完成了树莓派启动。我手中的树莓派是 Raspberry Pi 3 Model B 型,集成了蓝牙和 WIFI 模块。

    在 Mac 下用 ApplePi-Baker 安装树莓派系统非常方便,ApplePi-Baker 的界面如下图所示:

    WechatIMG1.jpeg
    1. 左侧选择要写入树莓派系统的 microSD Card;
    2. 右侧上方小窗口 IMG file 选择下载好的树莓派系统镜像(我一般使用树莓派官方制作的 RASPBIAN 镜像,可以从树莓派官网下载到);
    3. 然后点击右侧上方小窗口中的 Restore Backup 按钮,等进度条跑满就完成了树莓派系统的制作。

    接下来的操作就是将写好系统的 microSD Card 装进树莓派,开机。

    如果有一台显示器,可以选择相应树莓派操作系统的图形界面版本,将显示器、鼠标、键盘接入树莓派来实现普通桌面电脑的操作体验。我拿到树莓派的时候手边并没有可用的显示器,也并不打算通过外接键盘、鼠标的方式实现对树莓派的控制,所以下面介绍通过 SSH 方式连接树莓派。如果通过 SSH 方式连接树莓派,在写好系统后要新建一个名为 SSH 的文件放入 microSD Card 的根目录,以打开树莓派的 SSH 功能。然后进行如下操作:

    1. 将树莓派通过网线连接路由器;
    2. 通过路由器的管理界面查看树莓派目前使用的 IP 地址,记下这个地址(我的是:192.168.0.15);
    3. 树莓派的默认用户是 pi,密码是 raspberry ,通过以下命令可以连接到树莓派:ssh pi@192.168.0.15 WX20170415-215417@2x.png

    经过上面三步已经通过 SSH 方式连接到了树莓派,接下来我们可以让树莓派通过无线连接方式连接到路由器(当然得是无线路由器)。我使用的是树莓派官方制作的 RASPBIAN 系统,选择其他系统可能操作不同。

    1. 查看可用的网路,必须使用 sudo (这步非必须,如果知道无线路由器的 ESSID 的话): sudo iwlist wlan0 scan 记下要连接的无线路由器的 ESSID:WX20170415-220916@2x.png
    2. 编辑 /etc/wpa_supplicant/wpa_supplicant.conf,添加无线网络配置: network={ ssid="Targaryen-Cloud" psk="your-password" }
    3. 重启系统,拔掉网线,通过路由器管理界面可以看到树莓派已经通过新的无线方式连接到路由器了。

    这一步结束后路由器可能会为树莓派分配新的 IP 地址,所以 SSH 连接树莓派时注意切换新的 IP 地址!

  • 在树莓派上安装 Docker 记录

    在树莓派上安装 Docker 记录

    树莓派默认源中的 Docker 版本太老了,一些 Docker 的新特性无法尝试,这里尝试在树莓派上安装新版本的 Docker。安装方法主要参考了开源中国的一篇文章 《Raspberry-jessie Docker 安装记》。如果去看原文并且也只是想安装 Docker 的话 ,建议从原文的第 5 步开始看起,前面是作者的试错过程。这里将可以成功在树莓派上安装新版本 Docker 的关键步骤整理如下:

    1. 添加源到系统,这里使用的是阿里的源,将 debhttp://mirrors.aliyun.com/docker-engine/apt/reporaspbian-jessie main 加入到系统 /etc/apt/sources.list 文件中。
    2. 将 key F76221572C52609D (这 key 是在添加源后执行 sudo apt-get update 的警告信息中获得的)添加到系统 apt-key 列表:gpg -a --export F76221572C52609D | sudo apt-key add -
    3. 安装 Dockersudo apt-get update sudo apt-get install docker-engine

    至此,完成了在树莓派上安装新版本 Docker 的全部过程!

    nature-2129493_1920.jpg