分类目录归档:程序生活

Program Life – Web

iOS 10.3下解决Charles抓包ssl证书信任问题

前言

  最近iPhone系统更新到ios 10.3后,在公司里用Charles抓包竟然出现了一些问题,https的请求都会失败,提示错误信息为Failure SSLHandshake: Received fatal alert: unknown_ca 和You may need to configure your browser or application to trust the Charles Root Certificate. 然而之前任何问题都没有,并且相关设置都正确:Mac上安装了Charles的根证书,并且设置了始终信任,然后手机上也登录了http://chls.pro/ssl安装了描述文件,一切都按正常程序走的,但是错误始终无法解决.这里Charles的相关使用不做介绍,不会使用的请参考本文结尾处唐巧大大的博文.

相关环境

  • Charles 4.0.2
  • iPhone 6s iOS 10.3.1

原因

设置->通用->描述文件->charles proxy custom root certificate

虽然charles的根证书已经在安装列表中显示,但它是被关闭的。在iOS 10.3之前,当你将安装一个自定义证书,iOS会默认信任,不需要进一步的设置。而iOS 10.3之后,安装新的自定义证书默认是不受信任的。如果要信任已安装的自定义证书,需要手动打开开关以信任证书。

解决

设置->通用->关于本机->证书信任设置-> 找到charles proxy custom root certificate然后信任该证书即可.

信任证书

后记

问题虽小,但是很有必要普及一下.这个设置证书信任的开关界面隐藏的很深,是iOS 10.3之后出现的(貌似是,至少之前我没见过).这个问题因此也只有在iOS 10.3的设备上才会出现,真是太意外了!因此作为iOS开发者,更新手机系统时,了解一下系统更新的相关内容也变得很有必要.

【转】银联的跨行清算体系架构分析

目前实现跨行清算的系统主要有银联跨行清算系统、第三方支付系统、人行的网上支付跨行清算系统(超级网银),本文主要介绍银联的跨行清算系统。

跨行清算业务与清算对象

首先从业务上讲,银联的支付清算包括清分和资金划拨两个环节。清分是指对交易日志中记录的成功交易,逐笔计算交易本金及交易费用(手续费、分润等),然后按清算对象汇总扎差习惯应收或应付金额,简言之,就是搞清楚今天应该向谁要多少钱,应该给谁多少钱;资金划拨是指通过特定的渠道和方式,完成应收应付资金的转移,简言之,就是明确通过何种渠道,拿回应收款、付出应付款。

银联的支付清算包括跨行清算和收单清算,二者的对象不同:跨行清算是针对收单机构和发卡机构的清算;收单清算是代替收单机构针对商户和收单专业化服务机构的清算。

清算资金的划拨方式

境内的跨行清算通过人行的大额支付清算系统完成资金划拨,银联可以主动借记或贷记成员机构的清算账户,通俗的将,借记就是我向别人要钱,贷记就是我给别人钱;境外的跨行清算通过银联代理清算银行(中行和汇丰),通过银行与银行直接的结算汇兑系统完成,但目前只能实现贷记结算;境内的收单清算可以通过人行的小额支付清算系统完成资金划拨,部分分公司保留通过当地人行票据交换系统完成资金划拨,但均只能实现贷记结算。

对账方式

对账方式根据自主清算和非自主清算进行区分。境内的跨行清算和收单清算均采用自主清算,相应的对账方式是先以银联清分结果为准,先行办理资金划拨,然后成员机构、第三方机构或商户再根据银联的对账文件,对比本身的交易明细,如果有错误就通过差错方式处置;外卡收单清算及部分跨境业务均采用非自主清算。

银联清算系统与大小额支付的关系

无论是跨行清算还是收单清算,银联都是作为一个特许参与者,加入大小额支付清算系统,完成银行卡交换业务的资金划拨。银联通过大额支付系统,实现境内成员机构清算账户之间的双向资金转移;银联通过小额支付系统和当地票据交换系统,实现与境内第三方机构和商户之间的单向资金转移。

在大额支付清算系统中,银联享有比商业银行更大的特权,因为银联可以借记或贷记对方的账户,商业银行只能贷记对方的账户。在大额支付清算系统中还享有借记特权的只有国债登记公司,而且其借记操作还需要国债作抵押。

场景案例说明

张三是工行的持卡人,他需要取现金,但是找不到工行的ATM机器,发现附近有建行的ATM机器,他只能去建行取款,整个过程就是跨行清算的过程,我们以这个场景为例,分析一下业务流程,具体交互流程见下面一张图。

 

以上的结构,很关键的一点是不同银行间如何进行通信。如果银行直接与银行开发接口,那n家银行就要有n*(n-1)个接口线路,显然是非常不经济且复杂的。可以通过两种方式显示:

  • 公共接口模式:定义通信网络定义标准接口,所有的银行都必须实现这个通信网络定义的api,新的银行如果想要接入这个通信网络,必须实现通信接口约定的协议。
  •  适配器模式:通信网络主动去连接所有的银行的接口,把所有银行的接口信息都接入里面,就像一个适配器,新的银行如果想要接入这个通信网络,这个通信网络必须主动联系银行,按照银行的接口协议实现通信。

对于这两模式,主要博弈就在于谁强谁弱。显然第三方支付公司属于适配器模式,需要一家一家银行去接入,银联应该是第一种模式,这种对于银联这种需要稳定的系统来说是最具有优势的。

此外,就是如果跨行之间每笔交易都实时清算,那交易量太大,而且可能涉及到两个银行之间的频繁资金划转,,对最终清算的人行系统压力也会很大,例如日间如果发生:

A用户从工行ATM支取建行卡200元;

B用户从建行ATM支取工行卡100元;

C用户从建行ATM支取工行卡150元;

实际上只需要发生交易时工行和建行进行记账,日末工行统一转账给建行50元即可。

为了保障扎差资金划转时每个银行有足够的资金进行清算,各接入行需要再人行开立备付金账户,同时各银行会在内部开立相应的虚拟账户对应在人行的备付金账户,以便时候对账。

最后对于前面账户在建行ATM机取工行卡100元的案例,处理流程为:

1. 系统T日发生建行和工行的跨行交易100

2. 清算系统T+1日汇总T日工行和建行之间发生的交易明细数据,并且发这些数据发给建行和工行进行确认

3. 工行建行分别对明细对账确认之后,通知清算系统确认交易明细无误,清算系统开始清算,调用备付金支付系统转账

4. 清算完成之后,工行和建行分别获取备付金系统的真实金额和自身系统内部的映射账户进行余额对账(对账包括两个部分,一个是跨行交易明细的对账以及备付金余额的对账)

清分清算流程

清分清算主要有3个关键点:扎差清分、两级清算;支付系统、集中处理;日切,划分交易时间。

整体的系统结构图

最后:支付清算体系是一个国家的金融基础设施,或说公共服务。我国由央行主管此事,目前大体维持“结算-清算”二级制的支付体系。通俗地讲,银行与商户、消费者之间为结算关系,而银行之间构成清算关系,两个层次交易完成后,支付环节才算终了。清算,其实就是因跨行交易而产生的银行间债务债权进行定期净轧(比如每日),以结清因跨行交易产生的债务债权。清算更为底层,是一个平台,由央行主导建设,一般个人用户不会直接接触清算系统。结算则是前端,由银行、非金支付公司等向客户提供服务,也就是所谓的支付业务。银行自身接入清算系统,非金融支付公司则以自已开户的备付金托管行代理,接入清算系统。

Next主题(Hexo)

Hexo 有三种默认布局:post , page 和 draft
它们分别对应不同的路径,而您自定义的其他布局和post
相同,都将储存到 source/_posts文件夹。
也同时只有这个会被发布到服务器

配置文件_config.yml 有两个
前者称为 站点配置文件, 后者称为 主题配置文件。

添加头像
编辑 站点配置文件, 新增字段 avatar, 值设置成头像的链接地址。其中,头像的链接地址可以是:

  • 方式1
    将头像放置主题目录下的 source/uploads/ (新建uploads目录若不存在)
    配置为:avatar: /uploads/avatar.png

或者 放置在 source/images/ 目录下
配置为:avatar: /images/avatar.png

  • 方式2

    Paste_Image.png

设置语言

修改后网站图标都变成了中文字体

Paste_Image.png

编辑站点配置文件
English en language: en
简体中文 zh-Hans language: zh-Hans
如:

Paste_Image.png

作者昵称,站点描述

均为编辑站点配置文件

Paste_Image.png

Paste_Image.png

next还有主题可以设置

Muse – 默认 Scheme,这是 NexT 最初的版本,黑白主调,大量留白
Mist – Muse 的紧凑版本,整洁有序的单栏外观
Pisces – 双栏 Scheme,小家碧玉似的清新

Scheme 的切换通过更改 主题配置文件

#scheme: Muse
#scheme: Mist
scheme: Pisces

设置 下面 侧栏 的位置

通过修改 主题配置文件 中的 sidebar
字段来控制侧栏的行为

Paste_Image.png

注意 目前仅 Pisces Scheme 支持 position

sidebar:
  # Sidebar Position, available value: left | right
  #position: left            //控制sideba的位置
  position: right

  # Sidebar Display, available value:
  #  - post    expand on posts automatically. Default.
  #  - always  expand for all pages automatically
  #  - hide    expand only when click on the sidebar toggle icon.
  #  - remove  Totally remove sidebar including sidebar toggler.
  display: post               //控制sidebar的显示时机 
  #display: always
  #display: hide
  #display: remove
post 
- 默认行为,在文章页面(拥有目录列表)时显示
always
 - 在所有页面中都显示
hide
 - 在所有页面中都隐藏(可以手动展开)
remove
 - 完全移除

设置 菜单(重点)

菜单配置包括两个部分,

  • 第一是菜单项(名称和链接)
  • 第二是菜单项的显示文本
  • 第三是菜单项对应的图标

NexT 使用的是 Font Awesome 提供的图标

一 菜单映射的链接

修改主题配置文件

menu:
  home: /
  archives: /archives
  #about: /about
  #categories: /categories
  tags: /tags
  #commonweal: /404.html

二 菜单显示文本

(第一步中设置的菜单的名称并不直接用于界面上的展示。Hexo 在生成的时候将使用 这个名称(如home) 查找对应的语言翻译,并提取显示文本)

这些翻译文本放置在 NexT 主题目录下的 languages/{language}.yml
({language}
为你所使用的语言)。

menu:
  home: 首页
  archives: 归档
  categories: 分类
  tags: 标签
  about: 关于
  search: 搜索
  commonweal: 公益404
  something: 有料

自定义菜单

以简体中文为例,若你需要添加一个菜单项,比如 something。

1. menu
  something : /something 
 2. menu (比如主题目录下的language目录下的zh-Hans.yml)
  something: 有料
3. 设置图标

那么就需要修改简体中文对应的翻译文件 languages/zh-Hans.yml,在 menu
字段下添加一项:
something: 有料

三 设置菜单的图标

此设定格式是 item name: icon name

icon name 是 Font Awesome 图标的 名字

menu_icons:
  enable: true   // 是否显示图标
  # Icon Mapping.
  home: home
  about: user
  categories: th
  tags: tags
  archives: archive
  commonweal: heartbeat

item name 这3步骤都会用到 也就是键

设置社交链接

Paste_Image.png

Paste_Image.png

和设置Menu类似
因为仅仅配置了一个 Github链接,故仅仅显示一个

建立页面

直接在根目录的source路径下,新建一个404.html文件,就可以了
直接在根目录的source路径下,新建一个404.html文件,就可以了
然后可以配置 menu 映射下就可以在 上面显示

love: /404.html

Paste_Image.png

当然 通过
hexo new page “love”
会在source目录下生成一个文件夹
source/love/index.md
这也是建立页面的一种方式

添加Menu时候映射
love: /love 即可(localhost:4000/love 实际上访问是localhost:4000/love/index.html)

友情链接

Paste_Image.png
# Blogrolls
links_title: 友情链接
#links_layout: block
#links_layout: inline
links:
  Java学习天地: https://wangli0.github.com
  ruulai.com: https://wangli0.github.com
  视听中国: https://wangli0.github.com

绚丽的图片文章

可能有人对这个
Reading页面中图片的fancybox
效果感兴趣,这个是怎么做的呢。
很简单,只需要在你的文章*.md文件的头上添加 photos 项即可,然后一行行添加你要展示的照片:

layout: photo
title: 我的阅历
date: 2085-01-16 07:33:44
tags: [hexo]
photos:
 - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
 - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg

经过测试,文件头上的layout: photo可以省略。

不想每次都手动添加怎么办?同样的,打开您的
hexo/scaffolds/photo.md

---
layout: {{ layout }}
title: {{ title }}
date: {{ date }}
tags: 
photos: 
---

然后每次可以执行带layout的new命令生成照片文章:
hexo new photo “photoPostName” #新建照片文章

如 :

---
layout: photo
title: girls
date: 2016-12-21 14:58:55
tags:
photos:
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg

## girls looks well
测试...

小问题

Paste_Image.png

此列表的多少与 文章编写时候添加的标签和分类有关,自动添加
无需我们操心

文章中添加标签或分类
在文章中点击或者标签或分类跳转没问题
但是自己配置显示menu的分类和标签跳转找不到路径的问题

注意点

布局(Layout)
Hexo 有三种默认布局:post、page 和 draft,
它们分别对应不同的路径,而您自定义的其他布局和post
相同,都将储存到 source/_posts
文件夹。

模版(Scaffold)
在新建文章时,Hexo 会根据 scaffolds
文件夹内相对应的文件来建立文件,例如:
$ hexo new photo “My Gallery

在执行这行指令时,Hexo 会尝试在 scaffolds
文件夹中寻找 photo.md,并根据其内容建立文章

以下是您可以在模版中使用的变量:

Paste_Image.png

添加 类别和tags列表 (wen)

添加标签


hexo new page tags
确认站点配置文件里有tag_dir: tags
确认主题配置文件里有tags: /tags
编辑站点的source/tags/index.md,添加

title: tags
date: 2015-10-20 06:49:50
type: “tags”
comments: false


  • 添加分类
    hexo new page categories
    确认站点配置文件里有category_dir: categories
    确认主题配置文件里有categories: /categories
    编辑站点的source/categories/index.md,添加

title: categories
date: 2015-10-20 06:49:50
type: “categories”
comments: false

问题解决:
http://www.zhihu.com/question/29017171

图片资源的使用

Paste_Image.png

source 文件夹下面的文件在执行 hexo g 后 会把source下的所有文件放在public 文件夹下面。
public相等于网站根目录 \

Paste_Image.png

至于本地图片如何使用,如下所示

---
layout: photo
title: girls
date: 2016-12-21 14:58:55
tags:
photos:
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg
---

## girls looks well

Paste_Image.png

如何删除Hexo博客底部页脚

如:

Paste_Image.png

找到/themes/next/layout/_partials/footer.swig文件
内容如下:

<div class="copyright" >
  {% set current = date(Date.now(), "YYYY") %}
  © {% if theme.since and theme.since != current %} {{ theme.since }} - {% endif %}
  <span itemprop="copyrightYear">{{ current }}</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">{{ config.author }}</span>
</div>

<div class="powered-by">
  {{ __('footer.powered', '<a class="theme-link" href="https://hexo.io">Hexo</a>') }}
</div>

<div class="theme-info">
  {{ __('footer.theme') }} -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.{{ theme.scheme }}
  </a>
</div>

删除class 为powered-by的div和theme-info的div即可


最终内容

<div class="copyright" >
  {% set current = date(Date.now(), "YYYY") %}
  © {% if theme.since and theme.since != current %} {{ theme.since }} - {% endif %}
  <span itemprop="copyrightYear">{{ current }}</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">{{ config.author }}</span>
</div>

 

文/编程之乐(简书作者)
原文链接:http://www.jianshu.com/p/5d5931289c09
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。Hexo 有三种默认布局:post , page 和 draft
它们分别对应不同的路径,而您自定义的其他布局和post
相同,都将储存到 source/_posts文件夹。
也同时只有这个会被发布到服务器

配置文件_config.yml 有两个
前者称为 站点配置文件, 后者称为 主题配置文件。

添加头像
编辑 站点配置文件, 新增字段 avatar, 值设置成头像的链接地址。其中,头像的链接地址可以是:

  • 方式1
    将头像放置主题目录下的 source/uploads/ (新建uploads目录若不存在)
    配置为:avatar: /uploads/avatar.png

或者 放置在 source/images/ 目录下
配置为:avatar: /images/avatar.png

  • 方式2

    Paste_Image.png

设置语言

修改后网站图标都变成了中文字体

Paste_Image.png

编辑站点配置文件
English en language: en
简体中文 zh-Hans language: zh-Hans
如:

Paste_Image.png

作者昵称,站点描述

均为编辑站点配置文件

Paste_Image.png

Paste_Image.png

next还有主题可以设置

Muse – 默认 Scheme,这是 NexT 最初的版本,黑白主调,大量留白
Mist – Muse 的紧凑版本,整洁有序的单栏外观
Pisces – 双栏 Scheme,小家碧玉似的清新

Scheme 的切换通过更改 主题配置文件

#scheme: Muse
#scheme: Mist
scheme: Pisces

设置 下面 侧栏 的位置

通过修改 主题配置文件 中的 sidebar
字段来控制侧栏的行为

Paste_Image.png

注意 目前仅 Pisces Scheme 支持 position

sidebar:
  # Sidebar Position, available value: left | right
  #position: left            //控制sideba的位置
  position: right

  # Sidebar Display, available value:
  #  - post    expand on posts automatically. Default.
  #  - always  expand for all pages automatically
  #  - hide    expand only when click on the sidebar toggle icon.
  #  - remove  Totally remove sidebar including sidebar toggler.
  display: post               //控制sidebar的显示时机 
  #display: always
  #display: hide
  #display: remove
post 
- 默认行为,在文章页面(拥有目录列表)时显示
always
 - 在所有页面中都显示
hide
 - 在所有页面中都隐藏(可以手动展开)
remove
 - 完全移除

设置 菜单(重点)

菜单配置包括两个部分,

  • 第一是菜单项(名称和链接)
  • 第二是菜单项的显示文本
  • 第三是菜单项对应的图标

NexT 使用的是 Font Awesome 提供的图标

一 菜单映射的链接

修改主题配置文件

menu:
  home: /
  archives: /archives
  #about: /about
  #categories: /categories
  tags: /tags
  #commonweal: /404.html

二 菜单显示文本

(第一步中设置的菜单的名称并不直接用于界面上的展示。Hexo 在生成的时候将使用 这个名称(如home) 查找对应的语言翻译,并提取显示文本)

这些翻译文本放置在 NexT 主题目录下的 languages/{language}.yml
({language}
为你所使用的语言)。

menu:
  home: 首页
  archives: 归档
  categories: 分类
  tags: 标签
  about: 关于
  search: 搜索
  commonweal: 公益404
  something: 有料

自定义菜单

以简体中文为例,若你需要添加一个菜单项,比如 something。

1. menu
  something : /something 
 2. menu (比如主题目录下的language目录下的zh-Hans.yml)
  something: 有料
3. 设置图标

那么就需要修改简体中文对应的翻译文件 languages/zh-Hans.yml,在 menu
字段下添加一项:
something: 有料

三 设置菜单的图标

此设定格式是 item name: icon name

icon name 是 Font Awesome 图标的 名字

menu_icons:
  enable: true   // 是否显示图标
  # Icon Mapping.
  home: home
  about: user
  categories: th
  tags: tags
  archives: archive
  commonweal: heartbeat

item name 这3步骤都会用到 也就是键

设置社交链接

Paste_Image.png

Paste_Image.png

和设置Menu类似
因为仅仅配置了一个 Github链接,故仅仅显示一个

建立页面

直接在根目录的source路径下,新建一个404.html文件,就可以了
直接在根目录的source路径下,新建一个404.html文件,就可以了
然后可以配置 menu 映射下就可以在 上面显示

love: /404.html

Paste_Image.png

当然 通过
hexo new page “love”
会在source目录下生成一个文件夹
source/love/index.md
这也是建立页面的一种方式

添加Menu时候映射
love: /love 即可(localhost:4000/love 实际上访问是localhost:4000/love/index.html)

友情链接

Paste_Image.png
# Blogrolls
links_title: 友情链接
#links_layout: block
#links_layout: inline
links:
  Java学习天地: https://wangli0.github.com
  ruulai.com: https://wangli0.github.com
  视听中国: https://wangli0.github.com

绚丽的图片文章

可能有人对这个
Reading页面中图片的fancybox
效果感兴趣,这个是怎么做的呢。
很简单,只需要在你的文章*.md文件的头上添加 photos 项即可,然后一行行添加你要展示的照片:

layout: photo
title: 我的阅历
date: 2085-01-16 07:33:44
tags: [hexo]
photos:
 - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
 - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg

经过测试,文件头上的layout: photo可以省略。

不想每次都手动添加怎么办?同样的,打开您的
hexo/scaffolds/photo.md

---
layout: {{ layout }}
title: {{ title }}
date: {{ date }}
tags: 
photos: 
---

然后每次可以执行带layout的new命令生成照片文章:
hexo new photo “photoPostName” #新建照片文章

如 :

---
layout: photo
title: girls
date: 2016-12-21 14:58:55
tags:
photos:
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg

## girls looks well
测试...

小问题

Paste_Image.png

此列表的多少与 文章编写时候添加的标签和分类有关,自动添加
无需我们操心

文章中添加标签或分类
在文章中点击或者标签或分类跳转没问题
但是自己配置显示menu的分类和标签跳转找不到路径的问题

注意点

布局(Layout)
Hexo 有三种默认布局:post、page 和 draft,
它们分别对应不同的路径,而您自定义的其他布局和post
相同,都将储存到 source/_posts
文件夹。

模版(Scaffold)
在新建文章时,Hexo 会根据 scaffolds
文件夹内相对应的文件来建立文件,例如:
$ hexo new photo “My Gallery

在执行这行指令时,Hexo 会尝试在 scaffolds
文件夹中寻找 photo.md,并根据其内容建立文章

以下是您可以在模版中使用的变量:

Paste_Image.png

添加 类别和tags列表 (wen)

添加标签


hexo new page tags
确认站点配置文件里有tag_dir: tags
确认主题配置文件里有tags: /tags
编辑站点的source/tags/index.md,添加

title: tags
date: 2015-10-20 06:49:50
type: “tags”
comments: false


  • 添加分类
    hexo new page categories
    确认站点配置文件里有category_dir: categories
    确认主题配置文件里有categories: /categories
    编辑站点的source/categories/index.md,添加

title: categories
date: 2015-10-20 06:49:50
type: “categories”
comments: false

问题解决:
http://www.zhihu.com/question/29017171

图片资源的使用

Paste_Image.png

source 文件夹下面的文件在执行 hexo g 后 会把source下的所有文件放在public 文件夹下面。
public相等于网站根目录 \

Paste_Image.png

至于本地图片如何使用,如下所示

---
layout: photo
title: girls
date: 2016-12-21 14:58:55
tags:
photos:
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-0.jpg
  - http://bruce.u.qiniudn.com/2013/11/27/reading/photos-1.jpg
---

## girls looks well

Paste_Image.png

如何删除Hexo博客底部页脚

如:

Paste_Image.png

找到/themes/next/layout/_partials/footer.swig文件
内容如下:

<div class="copyright" >
  {% set current = date(Date.now(), "YYYY") %}
  © {% if theme.since and theme.since != current %} {{ theme.since }} - {% endif %}
  <span itemprop="copyrightYear">{{ current }}</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">{{ config.author }}</span>
</div>

<div class="powered-by">
  {{ __('footer.powered', '<a class="theme-link" href="https://hexo.io">Hexo</a>') }}
</div>

<div class="theme-info">
  {{ __('footer.theme') }} -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.{{ theme.scheme }}
  </a>
</div>

删除class 为powered-by的div和theme-info的div即可


最终内容

<div class="copyright" >
  {% set current = date(Date.now(), "YYYY") %}
  © {% if theme.since and theme.since != current %} {{ theme.since }} - {% endif %}
  <span itemprop="copyrightYear">{{ current }}</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">{{ config.author }}</span>
</div>
文/编程之乐(简书作者)
原文链接:http://www.jianshu.com/p/5d5931289c09
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

基于 Hexo 的全自动博客构建部署系统

转载自: http://kchen.cc/2016/11/12/hexo-instructions/

在互联网渗透到个人,自媒体信息爆炸的今天,大家都希望有一个归自己所有、掌控的个人博客。因为无论是记录生活,还是分享技术,自定义博客都可以按照自己的要求,为自己提供熨帖的服务,而不必受到条条框框的限制。但是普通用户又囿于没有高超的编程技术和前端本领,而在自定义博客面前望而却步了。本文的目标就是通过介绍 Hexo+Github/Coding.net+Travis+CloudXNS 形成一套完整的个人博客自动构建、部署、国内国外双线路负载均衡的系统。真正做到随时随地写文章,一键部署到网站的全自动化流水线。

什么是 Hexo

Hexo is a fast, simple & powerful blog framework.

Hexo 是一个极速、简单且强大的静态博客架构。它使用 Node.js 作为构建引擎,上百个文件在几秒钟内便可构建完成;而且拥有着丰富的插件库,因开源而显得生机勃勃,可扩展性很好;最重要的,它支持 Markdown 作为书写语言,极大地方便了博客的撰写。

安装 Hexo

Hexo 的安装和使用都非常便捷。但是,你的计算机环境中必须有这两个东西:

其中 Node.js 是 Hexo 的构建引擎,Git 是版本控制工具,关于二者的介绍和安装我就不在这里赘述了。Mac 用户推荐使用 Homebrew 进行安装。安装完成后,我们在终端中键入以下命令确认安装结果:

1
2
node -v
git –version

如果你的环境没有问题的话,那么我们就可以安装 Hexo 了:

1
npm install hexo-cli -g

安装完成后,进入一个目录作为存放博客资源的目录,然后:

1
2
3
4
hexo init blog
cd blog
npm install
hexo server

不出意外的话,终端中输出这样的结果

1
2
INFO Start processing
INFO Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.

那么恭喜,你的博客已经构建成功了!你可以到输出结果指定的地址去访问你的博客了。

hexo-init

撰写博文

撰写博文也非常简单,在你的博客目录 blog 下键入命令:

1
hexo new post <title>

就可以新建一篇博文了,如果你想写一篇草稿,而不发布的话,那么你可以键入:

1
hexo new draft <title>

首先我们来创建一篇名为 hello 的博文吧。

1
hexo new post hello

生成的源文件路径是:

1
INFO Created: <blog-dir>/source/_posts/hello.md

我们可以用任何的编辑器打开这个文件。

1
2
3
4
5
title: hello
date: 2016-11-12 12:39:20
tags:

这是 post 模板自动帮我生成的 yaml 文件头。其中 title 是博文的标题,我们可以改成「你好!」;tags 是博文的标签,我们可以加上「demo」、「hello」两个标签,从第 7 行开始我们就可以撰写博客的正文了。假设我写好的博客如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
title: 你好
date: 2016-11-12 12:39:20
tags:
– demo
– hello
欢迎来到 [Hexo](https://hexo.io/)!这是你的第一篇博文。
## 快速开始
### 创建一篇新博文
$ hexo new post “My New Post”
更多信息……
## 结语
谢谢你使用 Hexo。

然后保存这篇文章,之后访问 http://localhost:4000 你便可以看到这篇文章已经发布到你的博客中了(注意:hexo server 需要保持运行才能访问)。是不是非常的简单?

first-post

更多信息,请查阅 Hexo 的官方文档

博客部署

上文提到的博客,其实是通过 hexo server 搭建在本地的一个临时服务器,只有自己通过 http://localhost:4000 才能访问到,如果你想要把自己的博客发布的互联网上,你需要利用一个服务器来部署你的博客。

Hexo 是基于静态页面的博客系统,意味着对服务器的要求可以非常的低。低到什么程度呢?GithubCoding.net 就提供了免费的静态页面的托管服务,我们也就正好可以利用这个特性把我们的博客部署到这两个网站上面(为互联网的免费精神干杯?)。

我比较推荐把博客部署到 Github 上面,但是由于我国高墙的缘故,国内访问 Github 的速度有限,好在国内也有非常优秀的 Git 托管网站 Coding.net。所以国内用户可以非常方便的使用他家的免费服务来托管自己的博客,另外,我在后文还会介绍同时部署自己的博客到两个网站,然后利用 DNS 负载均衡技术来让国内国外访问分走不同线路实现全网加速,这是进阶教程了,我们先按下不表。

创建托管仓库

为了普适性和走国际化线路,本文以 Github 作为例子来介绍部署托管的流程。

我们用来托管博客的服务叫做 Github Pages,它是 Github 用来提供给个人/组织或者项目的网页服务,只需要部署到你的 Github Repository,推送代码,便可以实时呈现。

首先,你需要有一个 Github 的账号。然后创建一个名称为 <username>.github.io 的仓库来托管网页即可。

以我的 Github 为例,我的用户名是 quentin-chen,所以创建一个名为 quentin-chen.github.io 的仓库,创建的仓库地址便是:https://github.com/quentin-chen/quentin-chen.github.io.git 创建完后,我们可以暂时不用管它,不需要往仓库里面 push 任何的东西。

Hexo 部署配置

接着,我们来配置一下本地的 Hexo。

在博客的根目录下有一个名为 _config.yml 的文件,这是博客的主配置文件。前面的其他部分我们先不理会,后文再谈,我们先看最后的 Deployment 配置项:

1
2
3
4
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type:

根据官方的文档显示,现在 Hexo 支持 Git、Heroku、Rsync、OpenShift、FTPSync 等部署方式,我们选择 Git 来部署的话,需要首先安装 hexo-deployer-git 插件:

1
npm install hexo-deployer-git –save

然后编辑上面的配置文件

1
2
3
4
5
deploy:
type: git
repo: <repository url>
branch: [branch]
message: [message]

我们需要把刚才创建的仓库地址添加进来,branchmessage 项可以不填,默认情况下推送到 master 分支,这里我建议使用 SSH 加密的仓库地址(参看 Github 官方文档配置 SSH 免密操作)。

保存配置文件之后,我们在博客的跟目录键入:

1
2
hexo generate
hexo deploy

上述命令可以简化成

1
hexo g -d

便可以把博客部署到 Github 了。现在,所有人都可以通过 http://<username>.github.io 来访问自己的博客。

博客配置

前两章我们已经了解了 Hexo 的安装使用和如何部署自己的博客到 Github,现在我们来自定义一下我们博客。首先,主要的配置都在博客根目录的 _config.yml 文件里:

1
2
3
4
5
6
7
# Site
title: Hexo
subtitle:
description:
author: John Doe
language:
timezone:

这一组配置是博客的描述,titlesubtitle 分别是博客的站名,和副标题,description 对搜索引擎收录博客会有帮助。在多数主题中,一般只有标题和副标题会显示(我的主站只显示标题):

title

language 一般可以选配 en 或者 zh-cn,分别是英文和简体中文。

1
2
3
4
5
6
# URL
## If your site is put in a subdirectory, set url as ‘http://yoursite.com/child’ and root as ‘/child/’
url: http://yoursite.com
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:

这个部分需要修改的只有 url 选项,改成博客地址行了。后面的链接生成规则,保持不变即可。

1
2
3
4
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: landscape

这一组配置是用来定义主题和配置插件的,可以看到,官方默认的主题叫做 landscape,就是上面的那个那个天际地平线的主题了。Hexo 的社区非常非常的活跃,官方列表已经收录了 84 个制作精美的主题(字母升序排列,热度不分先后),每个主题都有很大的差别和不一样的特性,大家可以自行去列表中浏览、预览、选择自己喜欢的主题,总有一款适合你的胃口(没有就自己改?)。例如,我现在选择 yelee 主题:

1
git clone https://github.com/MOxFIVE/hexo-theme-yelee.git themes/yelee

把从官方列表中查到的主题仓库地址 git clone 下来,放到 themes/ 下相应的目录中,然后我们修改博客根目录下的 _config.yml 文件

1
theme: yelee

保存后,我们再次执行 hexo server 命令,预览一下网站的变化。

yelee

你看,主题是不是发生了巨大的改变,网站左侧现在显示的是 authorsutitle 了,右边的预览页面支持很多动态特效。每一个主题的详细配置参数都在 /themes/<yourtheme>/_config.yml 文件下,可以查阅该主题的官方页了解配置的解释。我在这里就不啰嗦了,当你选定了自己喜欢的主题,修改、配置好了之后。便可以使用、撰写、发布自己的博客了。

祝大家使用愉快,下面介绍 Hexo 的高阶教程。


域名和 DNS 负载均衡

绑定自定义域名

在前面的教程中,我们已经可以无碍的使用 Hexo 来写博客,可是有一个地方不太优雅,那就是域名。因为我们使用的是 Github 提供的二级域名 github.io,一来太长,二来也不太够自定义、个性化。关键是,你没有域名控制的自主权,DNS 和 CDN 都没法做,一切得看 Github 的网络环境。

所以,我们可以买一个域名,然后解析到 Github 去。关于选域名的问题,大家可以去看看博客搬迁记 – K.Chen,像我现在选购的 .cc 的顶级域名,每年才 19 元。一口气买 5 年不过才一顿饭的花费。还有不不少顶级域名如 .tech 才每年 5 元,这价格跟白开水一样。实在不济,还有 .tk.ml.cf.ga 四个免费域名提供开放注册(为互联网的免费精神干杯?)。域名在国内的万网、西部数码,国外的 Godady 等网站购买都是可以的。

购买域名之后,我们只需要把 DNS 解析创建两个 A 记录到:

1
2
3
4
5
192.30.252.153
192.30.252.154
如果使用 Coding.net,创建 CNAME 记录到:
pages.coding.me

之后在自己的博客根目录下创建一个 CNAME 文件,里面放你解析的域名。

之后修改根目录下的 _config.yml 文件,把站点地址更新成新的绑定的域名即可。

1
2
3
# URL
## If your site is put in a subdirectory, set url as ‘http://yoursite.com/child’ and root as ‘/child/’
url: http://yoursite.com

现在,就可以使用自己的域名访问自己的博客了,例如: http://kchen.cc

DNS 负载均衡

为了让国内国外都顺畅地访问我们的博客,我们可以把自己的博客同时部署到 Github 和 Coding.net:

1
2
3
4
5
6
7
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
– type: git
repo: https://github.com/quentin-chen/quentin-chen.github.io.git,master
– type: git
repo: git@git.coding.net:quentinchen/quentinchen.git,master

可是问题来了:

我只有一个域名,怎么让不同地方的人访问的时候给他不同地方的资源呢?

其实,这是一个典型负载均衡问题,就是把访问流量分流提高访问流畅性,只不过我们在这里还有穿越国内高墙限制的用途在里面。常见的负载均衡技术有 CDN 和 DNS 均衡等。

CDN 的做法是把网站常访问数据缓存到 CDN 服务器,当用户访问网站的时候 DNS 会把请求发送到离用户最近的 CDN 服务器上去。听起来是不是很棒?但是 CDN 服务一来挺贵,当然也有免费的,可是很难做到全球网络范围内的 CDN,另一方面流量都是 CDN 去帮我们做了,如果想有一些客制化的要求不容易实现。何况,其实 Github 和 Coding.net 自己本身就做了挺好的 CDN 加速,我们既然把博客托管在上面,善加利用就是了。所以我们采用 DNS 负载均衡来实现国内外分流。

大部分人可能天天都用着 DNS 却不知道它的基本原理,你可能知道我们访问互联网需要查询 DNS 服务器:

DNS

可是你知道它具体是怎么工作的么?

其实 DNS 系统是一个典型的树状架构,上图所示的 DNS 服务器其实应该叫 DNS 缓存查询服务器,它是为了减轻互联网上 DNS 查询的负载所设计的。如果你的请求没有命中缓存,那么这个缓存服务器就会自己进行一次标准查询,然后再把结果缓存起来,简单来说就是从根服务器开始一级一级的问。我们以前经常谈到根服务器的重要性其实就体现在这里了,它保留了对所有域名的起始解释权。

我国高墙常使用的一个技术手段称为 DNS 投毒,就是在根服务器上投毒,把需要墙的网站域名解析到不存在的地址上去。再配合地方的 DNS 劫持,你就别想访问到这些被墙的网站了。

根据 DNS 的特点我们可以使用 CloudXNS 提供的免费智能 DNS 解析服务(再次为互联网的免费精神干杯?)来动态解析我们域名。

为什么使用 CloudXNS 呢,不仅因为它免费,而且:

  • 不但拥有主流 DNS 产品的全部功能,而且扩展有自己独有的解析记录类型,在解析速度方面也明显优于国内其他同类产品,它的解析速度比传统 DNS 快两到三倍,DNS 配置生效更快,可做到实时生效。
  • 有非常多的线路选择,不仅可以按照海内、海外分类,甚至海内可以按照移动、联通、电信、铁通等等再划分到省级线路,海外可以详细到不同的地区和国家等上百条不同的解析线路:

routes

因为我们的博客始终是个小站,用不了那么多的线路区分,我们主要利用海内海外的线路来分流数据到 Github 和 Coding.net。

首先注册一个 CloudXNS 的账号,然后去原域名购买商处,将域名的 DNS 服务器指定为 CloudXNS 的服务器。

1
2
3
4
lv3ns1.ffdns.net
lv3ns2.ffdns.net
lv3ns3.ffdns.net
lv3ns4.ffdns.net

然后在 CloudXNS 设置你的域名,并添加如下域名解析:

balance

这样,默认访问将会被解析到 Coding.net,但是海外访问会被解析到 Github。非常方便。如果你的网站域名已经备案了的话,你还可以使用 CloudXNS 提供的免费 CDN 服务进一步为自己的网站提速。


Travis CI 持续集成

到这一步,你其实已经可以很简便的使用 Hexo 来写博客了,可人是一种永远不满足的动物。使用 Hexo 来写博客有一个问题就是,我只能在安装了 Hexo 的计算机上写东西,然后 hexo generatehexo deploy 到托管服务器。如果我想在没有安装 Hexo 的电脑上写博客呢?如果我想随时随地修改,或者写一下博客呢?

当然一个简单办法就是把自己博客的源文件也托管到 Github,每次都把源文件 clone下来,然后安装 Hexo,再构建发布就好了。可是这样做的话,始终不太优雅。那可以搞一个远程的服务器,把构建博客的事情交给服务器,每次要写博客的时候连接到服务器上去就行了。可既然我们把博客都托管到了 Github,为甚么博客的构建还需要服务呢?不行,这样还是不够优雅。如果有什么服务能够代替上述的那个服务器就好了,答案是确实有的——持续集成

什么是持续集成

持续集成(Continuous Integration)是一种软件开发实践。 在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以多次。 每次集成会经过自动构建(包括自动测试)的检验,以尽快发现集成错误。

什么是 Travis CI

Travis CI 是目前新兴的开源持续集成构建项目,它与 jenkins,GO 的很明显的特别在于采用 yaml 格式,同时它是在线的服务,不像 jenkins 需要你本地搭建服务器,简洁清新独树一帜。目前大多数的 Github 项目都已经移入到 Travis CI 的构建队列中,据说Travis CI 每天运行超过 4000 次完整构建。对于做开源项目或者 Github 的使用者,如果你的项目还没有加入 Travis CI 构建队列,那么我真的想对你说 OUT 了。

Travis 和 Hexo

为什么我们要选择 Travis 呢,因为它和 Github 集成的程度非常高,对于 Github 上的开源项目,可以免费在 Travis 上构建(我们是不是该为免费的互联网精神干杯?),而非开源的私有项目想在 Travis 上构建价格还是非常感人的。

我先把在 Travis 上进行自动构建的思路说一下:

sequence

  • 我们在在 Github 的博客仓库里新建一个 blog-source 分支,然后把博客的源码托管到这个分支
  • 每当我们在本地写好了博文之后,把修改 push 到该分支
  • Travis 上可以对这个项目的 blog-source 分支设置钩子,每当检测到 push 的时候就去仓库 clone 源代码
  • Travis 执行构建脚本
  • Travis 把构建结果通过 push 部署到 master 分支或者 Coding.net 的仓库里

在这样的自动化流程下,我们唯一需要做的事情就是 push 我们的博文到源代码分支,其他的事情交给 Travis,当然,这一流程是需要我们配置的。

配置 Travis

注册 Travis

Travis CI 不需要单独注册,直接使用 GitHub 账号登录就可以了。

官网会发现有 Sign in with GitHub(使用GitHUb登录)和 Sign Up(注册),其实这俩做的事情都一样,就是用 GitHub 账号登录。登录后界面会显示你的 GitHub Repository,默认全部全部没有勾选,选择你的博客的 Repository 后完成第一步,如图:

travis

如果你没有看到自己的项目,请点击右上角的 Sync with Github。

安装 Travis CML

在进行下面的步骤之前,我们需要先安装 Travis 的 CML,因为后面的部署需要我们加密的自己的 SSH 私钥和 Github、Coding.net 通信。安装过程请看 Travis CML Installation

首先必须有 Ruby 1.9.3 以上,检查了版本之后,安装 Travis,检查版本即可:

1
2
3
ruby -v
gem install travis -v 1.8.4 –no-rdoc –no-ri
travis version

如上,如果出现 1.8.2 这样的版本信息,则说明 Travis CI Command Line Client 安装成功。之后进行登录,执行:

1
travis login

按照提示登录就好了。

配置 Travis

在博客根目录下添加 Travis CI 所需要的配置文件 .travis.yml,配置文件内容和一些说明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
language: node_js
node_js: stable
# assign build branches
branches:
only:
blog-source
# cache this directory
cache:
directories:
node_modules
# S: Build Lifecycle
before_install:
openssl aes-256-cbc -K $encrypted_a0b7f0848317_key -iv $encrypted_a0b7f0848317_iv -in ./.travis/id_rsa.enc -out ~/.ssh/id_rsa -d
chmod 600 ~/.ssh/id_rsa
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
cp .travis/ssh_config ~/.ssh/config
npm install -g hexo-cli # 安装 hexo
git clone -b mod https://github.com/quentin-chen/hexo-theme-even.git themes/even
install:
npm install # 安装 package.json 中的插件
script:
hexo generate
after_success:
git config –global user.name “Quentin_Chen”
git config –global user.email “quentin.chen@foxmail.com”
sed -i “/^ *repo/s~github\.com~${githubToken}@github.com~” _config.yml
hexo deploy
# E: Build LifeCycle

我逐步来讲解一下每一个配置项的意思。

1
2
3
4
5
6
7
8
9
10
11
12
language: node_js
node_js: stable
# assign build branches
branches:
only:
blog-source
# cache this directory
cache:
directories:
node_modules

这里指定了构建的环境是 Node.js,版本是当前稳定版本。设置的 WebHook 钩子只检测 blog-source 分支的 push 变动。另外我们把 node_modules 文件夹放入缓存,这样可以大大节约每次构建的时间(2min -> 30s)。

1
2
3
4
5
6
7
8
before_install:
openssl aes-256-cbc -K <you_key> -iv <your_iv> -in ./.travis/id_rsa.enc -out ~/.ssh/id_rsa -d
chmod 600 ~/.ssh/id_rsa
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
cp .travis/ssh_config ~/.ssh/config
npm install -g hexo-cli # 安装 hexo
git clone <theme_repo> themes/<theme>

其实每次 Travis 构建的时候,相当于创建了一个干净的虚拟机,除了 Git 等必须的工具,甚至连 Node.js 的环境都是现安装的。所以我们在构建自己的博客之前,需要做一些环境的准备。

其中 2-6 行是用来配置 SSH 私钥的,这样才能让 Github 和 Coding.net 知道你的身份。这一部分我们后面再说。

第 7 行是在 Travis 中安装 Hexo 环境,第 8 行是安装主题。

关于主题这里,如果你对自己的主题做了修改(包括配置文件),那么应该把自己修改过的主题托管到 Github,这里填的 <theme_repo> 应是你自己地址。

1
2
3
4
5
6
7
8
9
10
install:
npm install # 安装 package.json 中的插件
script:
hexo generate
after_success:
git config –global user.name “<You Name>”
git config –global user.email “<email>”
hexo deploy

这一部分,就是在 Travis 上模拟部署过程。因为要使用 Git,所以要提前配置好 Committer 的信息。

生成私钥加密文件

什么是私钥?

私钥就是密钥对(密钥对指一对公钥和私钥),我们在使用 Github 的时候,首先需要在 Github 上配置公钥,这是最基础的。那么,存在我们本地的私钥就是你的个人身份标示,如果你的项目 git 地址配置的是 git@github.com:username/projectname.git(相对的还有 https://github.com/username/projectname.git), 当你在对 Repository 在一些操作(比如 push等),则需要私钥进行身份验证了(这是自动验证的,如果是使用 https 的配置,则需要提供用户名和密码)。

我们在 Travis CI 上自动部署代码,就牵扯到了 push 操作,那么就需要提供私钥了。

为什么生成私钥加密文件?

将私钥直接放在项目里,那么人人都能看到。私钥的泄露将会发生一系列的问题,比如有坏人拿你的私钥直接操作你的 git 项目,你能干啥他也能干啥(原理上面讲了),这咋整?我们需要对私钥进行加密。

Travis 提供了加密文件的支持,什么意思呢?我们可以对文件(这里指私钥)在本地进行加密,然后把加密过后的文件放在项目里,那么别人就无法获取里面的真实内容。然后我们在让 Travis 执行脚本的时候,在读取加密文件之前对文件进行解密(使用的解密密码提前在 Travis 上配置好了),这样就可以达到不将文件内容暴露,并且让 Travis 获取到真实内容的目的了,大概的时序图如下:

enc-key

开始吧,我们首先把自己的在博客的根目录下建立 .travis 文件夹来存放相关的资料:

1
mkdir .travis && cd .travis

把本地的私钥复制一份过来,用 Travis 加密,然后删除(切记加密完了一定要删除原始密钥!!!):

1
2
3
cp ~/.ssh/id_rsa .
travis encrypt-file id_rsa
rm id_rsa

现在 ls 命令查看一下 .travis 目录应该只有 id_rsa.enc 这一个文件才对。然后我们再在当前目录下新建一个 ssh_config 用来配置 Travis 上的 SSH Client。

1
2
3
4
5
Host *
User git
StrictHostKeyChecking no
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes

现在,我们在 Travis 网站,博客项目的设置(项目右上角)里可以看到两个用于解密私钥的环境变量:

travis-env

把这两个环境变量名复制到上面的 .travis.yaml 文件里替换相应部分:

1
2
before_install:
openssl aes-256-cbc -K <you_key> -iv <your_iv> -in ./.travis/id_rsa.enc -out ~/.ssh/id_rsa -d

这样,全部的配置就完成了。

Tips: Github 还支持 Application Token 的方式来认证身份,比使用 SSH 私钥要更简便,但考虑到 Coding.net 并不支持,我还是选择普适的方法。有兴趣的同学可以自己研究一下,就当做课后作业吧:D。

完成工作流

在进行工作流之前我们来检查一下我们现在工作目录和所有必须的东西:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.
├── .travis*
│   ├── id_rsa.enc
│   └── ssh_config
├── _config.yml*
├── db.json*
├── node_modules
├── package.json*
├── scaffolds*
├── source*
│   ├── CNAME*
│   ├── _posts
│   ├── about
│   ├── categories
│   ├── img
│   ├── media
│   └── tags
└── themes

我用星号标记的文件和文件夹都是十分重要的,确保 Git 覆盖了这些文件和目录,然后我们把目录 pushgithub/blog-source 仓库分支。Travis WebHook 立马就会检测到 push,然后开始构建了:

build-success

上图是一次成功的构建,我们可以点开 Job log 看一下构建过程的 Log 文件,特别是构建没有成功的话,我们更要仔细阅读,找准问题,对症下药。

构建成功以后再去刷新你的网页,是不是已经是最新的了呢?

总结

至此,这套教程就全部写完了。我们来回顾一下:

  • Hexo 的安装和使用
  • 配置博客和使用自定义主题
  • 部署自己的博客到 Github 或者 Coding.net 等静态页面托管服务
  • 利用 CloudXNS 对自己的域名进行动态解析,以加速国内国外的全网访问速度
  • 利用 Travis 实现全自动部署

希望你能学会,并爱上用这样的方式来写作博客!一切只是刚刚开始,可以折腾的东西还有好多好多,祝你玩得愉快!

在操作过程中有什么疑问,欢迎在下方留言。大家一起交流讨论。

eclipse下安装js插件-spket(支持Ext) 能格式化Js(JQuery自动提示)

1、选择Help -> Software Updates -> Find and Install…-> Search for new features to install ->New remote site…
Name: “Spket”, Url: “http://www.agpad.com/update”下载完毕重启 Eclipse

2、Window -> Preferences -> Spket -> JavaScript Profiles -> New ;
输入“ExtJS”点击OK;
选择“ExtJS” 并点击“Add Library”然后在下拉条中选取“ExtJS”;
选择 “ExtJS”并点击“Add File”,然后在你的./ext-2.x/source目录中选取“ext.jsb” 文件;

3、设置新的ExtJS Profile,选中并点击“JavaScript Profiles” 对话框右手边的“Defalut”按钮;

4、JS打开方式为 Window -> Preferences ->General-> Editors-> File Associations设置js默认打开文件的方式为spket

通过微信公众号ID生成微信二维码

大家都知道,微信公众号对应的二维码只有管理员在后台才可以看到的,那非管理员如何生成一个公众号的二维码呢?

微信公众平台有一个get接口可以获取到

http://open.weixin.qq.com/qr/code/?username=xxxxxxxx

那个username换成微信公众号的id就行了

比如

http://open.weixin.qq.com/qr/code/?username=orangebank_sz000001

http://open.weixin.qq.com/qr/code/?username=ibankquan

“海蓝一键运动”-微信运动刷步数工具

iOS版本的微信运动刷步数工具

输入想增加的步数,点击“一键增加步数”即可刷新自己的微信运动步数,登上微信运动好友排行榜第一不是梦。
请不要滥用,还是要坚持锻炼,该软件仅供娱乐。
有问题可与我联系 微博@海蓝

效果如下图:

海蓝一键运动

weixinsport2

 

 

thumb_IMG_3060_1024

下载地址,用iPhone手机浏览器打开: http://pre.im/weixinsport

【转】银行清算系统的实现原理

 

最近看了很多银联方面的清算系统的设计原理,对于跨行清算系统有了很大的了解,写这篇文章的目的是在于从一个程序员的角度去思考一个跨行清算系统的架构是如何实现的以及整个过程中我们有哪些思想是可以借鉴的。由于金融里面涉及到太多的专业名词,包括借贷,备付金,头寸,调拨等等,这里不会涉及到这些,取而代之的是以大家可以理解的概念去解释。

下面简单的介绍一下两种跨行清算系统的实现原理以及特点。一种跨清算系统是我们最熟悉的银联,还有一种是越来越流行的第三方支付系统,比较典型的是快钱。

首先来拿生活中的一个非常常见的例子来说明跨行清算的整个过程,这里面不涉及交易费等其他概念。

跨行取款流程

张三是工行的持卡人,他需要取现金,但是找不到工行的ATM机器,发现附近有建行的ATM机器,他只能去建行取款,整个过程就是跨行清算的过程,我们以这个场景为例,分析一下业务流程,具体交互流程见下面一张图。

1B3CB2A3 1863 403C AA5A F1F49E7EF416

 

工行持卡人张三在建行ATM机器取款100,ATM请求建行主机,由于是工行的卡,建行不识别,只能请求工行去处理,工行识别持卡人账户并扣款100,然后通知建行,建行则通知atm吐钱。

这里整个系统要解决两个问题:

1 建行如何与工行通信

2 建行和工行之间如何清算,如上图结果,工行欠建行100.

整个系统的分析基于以上两个问题,下面首先解决是通信问题

 

跨行通信的两种模式

我们先假设工行提供接口,只需要建行发送指约定格式的报文,即可于工行通信,这种相当于建行直接通过接口方式与工行通信。如果是这种方式,只能解决建行和工行的单向通信,如果工行和建行通信,则工行要发送建行指定的通信报文格式。可是大家想想,如果银行更多怎么办,下面是三家银行间的通信

39A9848E 13A0 4F15 ABEB F1CE91BBAD73

当有三家银行的时候,通信链路就有3*2=6条,当银行越来越多的时候,这种点对点的通信变的越来越复杂,每新增一家银行,他要做之前银行都要做的很多重复性的劳动,这样的成本非常高,也不经济,那么必须出现一个网络,它能够接入所有的银行,新的银行只需要接入这个网络,就可以和其他所有的银行进行通信。

先把这个网络成为通信网络,这种通信网络有两种方式可以连接所有的银行

  • 1 这个通信网络定义标准接口,所有的银行都必须实现这个通信网络定义的api,新的银行如果想要接入这个通信网络,必须实现通信接口约定的协议。简称公共接口模式
  • 2 这个通信网络主动去连接所有的银行的接口,把所有银行的接口信息都接入里面,就像一个适配器,新的银行如果想要接入这个通信网络,这个通信网络必须主动联系银行,按照银行的接口协议实现通信,简称适配器模式。

下面一幅图演示了这两种模式的不同:

7BDB9C58 65C9 4F58 B9B0 EA37D977317E

对于这两模式,主要博弈就在于谁强谁弱。显然第三方支付公司属于适配器模式,需要一家一家银行去接入,至于银联,个人认为应该是第一种模式,这种对于银联这种需要稳定的系统来说是最具有优势的。

 

跨行清算保证金模式

解决了通信问题,下面就看如何解决资金的清算问题。一种简单的方案就是工行在建行里面开设一个保证金账户,用这个账户去偿还在整个跨行交易中应付给建行的资金。

88169047 B15D 422F 828E 685ADF9207D7

 

从上图来看,这种方案确实可行。只需要工行在建行里面放足额的保证金,就可以满足跨行的费用。但是这里面实际上存在非常多的问题,

  • 1 如果银行越来也多,每个银行都要在其他银行存钱,太不经济了
  • 2 保证金需要放多少资金?如果一直都没有发生跨行交易,工行就亏大发了
  • 3 如果保证金不够怎么办?交易失败还是记应收款?

对于第一个问题假设银行越来越多,会导致工行需要在其他每个银行里面都开设保证金账户(见下图),是一个很不经济的方案。

66D7CC71 8C84 4621 B234 3E06FAC5856F说明这个在其他银行存保证金的方案是不可行的,和之前通信的问题一样,是不是可以把所有的银行保证金账户单独管理起来,统一放置在一起,方便各个银行之间的清算。我们暂时把这个系统称之为保证金系统。

保证金系统

保证金就是方便各个银行之间的清算,需要单独由一个系统进行管理,解决了跨行之间保证金存放的问题。每个银行只需要在保证金系统中存点钱就可以了。保证金系统也有两种模式。先看看比较好理解的第一种模式:

EB1C0D6C C30F 4B7D A120 7CB46AC33DD3

在这种模式下,银行先把一部分钱存放在保证金系统里面,同时银行内部建立一个虚拟账户,记录存放了多少钱,主要是方便对账,万一这个保证金系统钱算错了怎么办。你可以想象一下,银行是很小气的,为啥愿意把钱存放到这保证金系统里面,这部分钱干啥不好,能够银行这么干的只有国家了,这个系统就是央行的备付金管理系统。每个新增的银行都要存一份钱在这里。

另外一种方案是倒过来思考,既然没有牛逼的央行作支撑,那可以在每个商业银行都建立一个账户,用这个账户负责和银行进行清算。每新增一家银行,就在那个银行里面开一个保证金账户。

EBA5972D 06C6 4DC7 A7E4 4CC68455988B

这两种方式有本质的不同,一个是银行把资金的一部分转出到保证金,银行建立虚拟账户和保证金里面真实的资金映射。一个是保证金系统把资金转出到各个银行,自己内部建立一个虚拟账户和银行中真实的资金账户进行映射。这个间接的银行了后续的对账机制,这里先不叙述。

所有的第三方支付公司跨行清算的流程都是第二种方式,只有国家级清算公司(比如银联)是第一种方式,这是一种资源和权力上的不平等,不过是可以理解的。

清算系统

保证金系统解决了保证金存放的问题,接下来就是解决如何清算的问题。假设保证金转账是实时的,就要面对上面说的问题,保证金不够的情况下,跨行交易是成功还是失败。这是一个业务上问题,有很多种解决方案,我们暂不说。从技术上来讲,如果每一笔交易都要保证金实时记账,那么保证金系统的负载太大,事务如何保证等等一些列的问题。所以一个最简单的方案就是:一天结算一次。

每天由一个系统记录这些跨行交易信息,汇总出来,统一记账。这样一天只需要调用一次保证金系统即可。那么整个清算过程则是下面的流程:

  • 1 系统T日发生建行和工行的跨行交易100

08F9F26D 11BC 4BCA 9FAD F5C9F7B9691C

  • 2 清算系统T+1日汇总T日工行和建行之间发生的交易明细数据,并且发这些数据发给建行和工行进行确认

111356A9 ECA8 490A 977A 1FCD613F054F

 

  • 3 工行建行分别对明细对账确认之后,通知清算系统确认交易明细无误,清算系统开始清算,调用保证金支付系统转账。
  • 4 清算完成之后,工行和建行分别获取保证金系统的真实金额和自身系统内部的映射账户进行余额对账。

C84544CD AE52 4D98 999C C8B587B3E6AE

 

清算中心最主要干得事情就是统计谁欠谁多少钱,以及触发保证金系统的调拨操作。

 

对账流程

对账包括两个部分,一个是跨行交易明细的对账以及保证金余额的对账。

首先要思考的是:对账是谁发起的 ? 这个是了解对账的本质。

我们举生活中的一个例子,我们把钱投资到一个人,那个人负责公司的日常运作。你肯定会主动了解公司的账务,因为那个是你的钱。对账的发起人也是如此,对于银联的清算过程,对账的发起者是商业银行,因为你把钱放在保证金系统里面,这是你的钱,你需要去关心这个的,银联可不关心这个。

对于另外一种保证金系统,把钱放在各个银行里面了,那么对账的发起者就是这个保证金系统维护者了。目前普遍的第三方支付公司都是这个模式,所以他要找各个银行要结果明细进行对账,确认自己的资金安全无误。

 

以上就是一个简单的跨行清算系统的雏形,从一个就简单的例子入手,说明一个清算过程。目前银联的第三方支付公司的清算过程大致如此,但是实现细节远比这个复杂。但是一个基本的清算系统的本质模型大体上是不会变的。当然这个只是对于同币种的清算,不同币种或者虚拟货币的清算会涉及到汇率的问题,这些就很复杂,有机会在研究一下,后续在分享。

PS:以上很多名词都是自己的随意写的,里面很多专业名词这里不提及,有兴趣的可以自己去了解。