Quartz初浅使用

1、Quartz 简介

本教程建立在 SSM 整合点 Maven 项目的商城网站上 实现概览:通过提交商品订单,限制用户在规定时间付款,若仍未付款达到规定时间取消订单动作。


  • 官方介绍

Quartz 是 OpenSymphony 开源组织在 Job scheduling 领域又一个开源项目,它可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。Quartz 可以用来创建简单或为运行十个,百个,甚至是好几万个 Jobs 这样复杂的程序。Jobs 可以做成标准的 Java 组件或  EJBs。 Quartz 用一个小 Java 库发布文件(.jar 文件),这个库文件包含了所有 Quartz 核心功能。这些功能的主要接口(API)是 Scheduler 接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

2、下载及其安装

2.1 下载

官方 Site: http://www.quartz-scheduler.org

Click 下 Download 即可下载最新 这里显示最新为 2.2.3

2.2 添加 Maven 依赖

一般使用 Quartz 以及 Spring4 框架整合使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.3</version>
</dependency>

和 Spring 整合,需要 spring-context-support 的 jar 包

3、简单剖析

Quartz 框架简单架构

  1. Schedule ——  核心调度器
  2. Job ——  任务
  3. JobDetail ——  执行任务器
  4. Tigger ——  触发器

使用方法:

  1. 制作一个任务 Job java 类 需要一个执行方法
  2. 将类放到 spring 容器内,注意需要注解
  3. 配置 jobDetail,指定相应的任务 job
  4. 配置一个 Tigger,编写一个由 corn 表达式的触发方法的触发器
  5. 配置一个配置调度工厂

执行流程图:

4、使用教程

4.1 创建一个 Job Java 类

值得注意需要声明 execute()

1
2
3
4
5
6
7
8
public class Scheduler1 {
public void execute()
{
System.out.println("The task has been completed...");
System.out.println("Tasks to complete!");
System.out.println(new Date());
}
}

4.2 配置 Spring

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
<!-- 配置job类 -->
<bean id="scheduler1" class="com.hmall.order.schedule.Scheduler1"></bean>
<!-- 配置JobDetail执行任务器 -->
<bean id="SpringQtzJobMethod"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="scheduler1"></ref> <!-- 要执行的job名称 -->
</property>
<property name="targetMethod"> <!-- 要执行的方法名称 -->
<value>execute</value>
</property>
</bean>
<!-- 配置Trigger调度触发器 -->
<bean id="CronTriggerBean"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="SpringQtzJobMethod"></property>
<property name="cronExpression" value="0/5 * * * * ?"></property>
</bean>
<!-- 配置调度工厂 -->
<bean id="SpringJobSchedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="CronTriggerBean"></ref>
</list>
</property>
</bean>

值得注意:
1. job:scheduler1 – jobDetail:scheduler1 job:SpringQtzJobMethod – Trigger:SpringQtzJobMethod Trigger:CronTriggerBean – FactoryBean:CronTriggerBean 2.需要使用 corn 表达式

4.3 运行调试

运行 Maven 项目  clean tomcat7:run

1
2
3
4
5
DEBUG - Calling execute on job DEFAULT.SpringQtzJobMethod
DEBUG - batch acquisition of 1 triggers
The task has been completed...
Tasks to complete!
Wed Jun 20 11:46:20 CST 2018

看到以上 success 即成功

5、Corn 表达式

Cron 表达式的说明

字段名 允许的值 允许的特殊字符
0-59 , - * /
0-59 , - * /
0-23 , - * /
1-31 , - * ? / L W C
1-12 or JAN-DEC , - * /
1-7 or SUN-SAT , - * ? / L C #
empty, 1970-2099 , - * /

Cron 字符的说明

字符名 字符说明
“?”字符 表示不确定的值
“,”字符 指定数个值
“-”字符 指定一个值的范围
“/”字符 指定一个值的增加幅度。n/m 表示从 n 开始,每次增加 m
“L”字符 用在日表示一个月中的最后一天,用在周表示该月最后一个星期 X
“W”字符 指定离给定日期最近的工作日(周一到周五)
“#”字符 表示该月第几个周 X。6#3 表示该月第 3 个周五

Cron 常用表达式案例说明

表达式 含义
0 0 12 ? 每天中午 12 点触发
0 15 10 ? 每天上午 10:15 触发
0 15 10 ? 每天上午 10:15 触发
0 15 10 ? * 每天上午 10:15 触发
0 15 10 ? 2005 年的每天上午 10:15 触发
0 *14 ** ? 在每天下午 2 点到下午 2:59 期间的每 1 分钟触发
0 0/5 14 ? 在每天下午 2 点到下午 2:55 期间的每 5 分钟触发
0 0/5 14,18 ? 在每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
0 0-5 14 ? 在每天下午 2 点到下午 2:05 期间的每 1 分钟触发
0 10,44 14 ? 3 WED 每年三月的星期三的下午 2:10 和 2:44 触发
0 15 10 ? * MON-FRI 周一至周五的上午 10:15 触发
0 15 10 15 * ? 每月 15 日上午 10:15 触发
0 15 10 L * ? 每月最后一日的上午 10:15 触发
0 15 10 ? * 6L 每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6L 2002-2005 2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
0 15 10 ? * 6#3 每月的第三个星期五上午 10:15 触发

Cron 表达式构造器

Site: http://cron.qqe2.com
Jar 软件: CronExpBuilder-1.0

在Icarus主题下开启评论模块

Valine

Valine评论插件的漏洞会导致此评论服务暴露所有评论者的IP地址 ([xCss/Valine#336](https://github.com/xCss/Valine/issues/336)) 请更换其他评论服务

何为 valine 评论?

Valine 诞生于 2017 年 8 月 7 日,是一款基于 LeanCloud 的快速、简洁且高效的无后端评论系统。 理论上支持但不限于静态博客,目前已有 Hexo、Jekyll、Typecho、Hugo、Ghost 等博客程序在使用 Valine。

和其他评论模块的优势

  • 属于国内的评论模块,在网站加载速度和人性化方面略优
  • LeanCloud 背书,有一定保障性
  • 无意义上后端,接入便捷
  • MarkDown 全语法支持,并支持 Emoji

注册 LeanCloud 并创建应用

注册 LeanCloud 成功后创建应用

点击设置-应用 Key 获得 App key 即创建成功,由于 LeanCloud 对免费用户开发版进行一系列限制,接下来开始对该应用进行设置。

设置 - API 访问域名

绑定自己已有在国内备案过的域名,在设置-域名绑定-API 访问域名设置。

  • 注意不可以填入自己的 GitHub page 的 URL,github.io 也不行会引起 403 ERROR
  • 国际版可以使用免费的二级域名,这里不推荐使用,因为体验过后不太佳,尽量还是使用自有域名

设置 - 云引擎、ClientEngine 域名

同上,绑定域名,显示已绑定即成功绑定。

配置 Icarus 的 config

打开部署的 Hexo 根目录,在 theme 下的 Icarus 文件夹里vi _config.yml开始配置配置项,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Comment plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/
comment:
type: valine
app_id: W3zVbpO*****gzGzoHsz
app_key: DUKL************Lb1hNyD5q3
placeholder: "欢迎留言…"
notify: false
verify: false
avatar: 'retro'
meta: ["nick", "mail"]
page_size: 10
highlight: true
record_ip: false

附带 - 参数解释

参数 配置 说明
type changyan,disqus,disqusjs,facebook,gitalk,gitment,isso,livere,utterances,valine [必填] 这里默认 valine
app_id W3zVbpO*****gzGzoHsz [必填] 为 LeanCloud 应用的 AppID
app_key DUKL************Lb1hNyD5q3 [必填] 为 LeanCloud 应用的 AppKey
placeholder 欢迎留言… [可选] 评论前提示语
notify false [可选]notify 邮件提醒无论 true 和 false 都是不生效的,因为 valine 评论自带的邮件提醒功能将在 v1.4.0 发布时下线
verify false [可选]评论时是否有验证码,如为 true 需要在 Leancloud 设置->安全中心 中打开图形验证码服务
avatar mp,identicon,monsterid,wavatar,retro,robohash,hide [可选]评论发表时,不填入邮箱 email 或无Gravatar 头像显示的头像类型,详细见Valine 针对 avatar 头像的说明
meta [“nick”, “mail”, “link”] [可选]分别对应评论栏所供填入的昵称、邮箱地址和个人网站
page_size 10 [可选]分页配置
highlight true [可选]是否开启高亮代码
record_ip false [可选]是否评论后显示 IP

至此,键入hexo clen & g重启服务即可看到评论模块生效成功。

申请推送流服务

QMsg

因某些原因,Qmsg 酱将要停业,并关闭新用户登录通道,原有用户可以继续使用到完全停业。感谢您一直以来对 Qmsg 酱的支持!

由于 QMsg 已经关闭注册入口,现在新增国内另外一家提供推送消息服务 ServerChan

ServerChan

「Server 酱」,英文名「ServerChan」,是一款「程序员」和「服务器」之间的通信软件。
说人话?就是从服务器推报警和日志到手机的工具。

进入ServerChan官网,按流程注册获取到SCKEY,在下方测试正常推送到关注好到微信公众号收到测试消息,即可成功。

安装 Valine-admin

首先确保上面流程走完且评论正常,方可展开 valine 后台部署,然后进入 LeanCloud 对应的应用,点击 云引擎 -> 部署 -> 部署项目 -> Git 部署 -> Git 配置 填写 GIt 代码库并保存:[https://github.com/sviptzk/Valine-Admin-Server](https://github.com/sviptzk/Valine-Admin-Server) 然后再次点击 Git 部署 第一次部署请勾选不使用缓存,最后点击部署,查看日志无报错且部署完成就此部署第一阶段完成。

配置部署后台的环境变量

点击 云引擎 -> 设置 -> 添加新变量:

变量名 示例 说明
SITE_NAME My_blog [必填] 网站名称
SITE_URL https:/bk.catooilg.com [必填] 网站地址,最后不要加 /
SMTP_USER postmaster@catooilg.com [必填] SMTP 服务用户名,一般为邮箱地址。
SMTP_PASS password [必填] SMTP 密码,一般为授权码或者是邮箱的登陆密码,请自行查询对应邮件服务商的获取方式
SMTP_SERVICE qiye.aliyun 邮件服务提供商,请查询对应到邮件服务商参数
填入
SENDER_NAME Yuki [必填] 寄件人名称。
TEMPLATE_NAME default [必填] 设置提醒邮件的主题,默认为
default,可以选择填入 default,rainbow,custom1,custom2
DISABLE_EMAIL true [可选],填写则代表停止发送邮件
SCKEY xxx [可选] 填入 ServerChan 的 SCKEY
FAVICON https://img.catooilg.com/catooilg/2016/07/valine_favicon.ico [可选] 网页 favicon 图标

添加完成后,点击保存,并且重新部署实例即可。

初始化后台管理

第一次打开绑定的域名会提示需要登录,在域名后补上 /sign-up,先注册你的登录信息,即可进入后台进行管理操作。

设置防休眠

点击 云引擎 -> 定时任务,新增定时器,配置如图所示:

保存后运行即可。

常见问题

Q:提示 undefined is not a valid value
自定义环境变量没有配置好,请再次检查

Q:提示 Invalid status code: { favicon: ‘https://cdn.jsdelivr.net/gh/sviptzk/StaticFile_HEXO@v3.2.3/butterfly/img/favicon.ico‘ }
自定义环境变量网页 favicon 图标没有配置好,注意是否 ico 图标(尺寸为 48 × 48)

Waline

✖ Project framework failed to execute:
ERROR:
Please provide existed ossBucket under your account when code size is greater than 50M.

致谢与引用声明

Hexo 优化 — Valine 扩展之邮件通知
Valine 评论之 Valine-admin 配置攻略
Valine 官方文档
Qmsg 酱-您的专属 QQ 消息推送服务小姐姐
Server 酱 | 网站小帮手

部署Hexo博客

初次见面:

Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。

**
准备事项:

  • 自有服务器
  • 前端静态资源存储器,诸如 Gitee Pages/Github Page 等

**
参考文章:
hexo 官方中文文档

于 CentOS 部署 hexo**

Hexo 是一个基于 nodejs 的静态博客网站生成器,作者是来自台湾的 Tommy Chen 一道指令即可快速生成支持 Markdown 的静态博客

部署程序

1.1 安装 NVM (可选)

wget -qO- [https://raw.github.com/creationix/nvm/master/install.sh](https://raw.github.com/creationix/nvm/master/install.sh) | sh

1.2 安装 Nodejs

nvm install stable
亦或者官网下载部署安装,检查是否安装成功
node -vnpm -v

1.3 下载与安装 Hexo

npm install -g hexo-cli
下载完毕中会告知你下载路径存放点,接着需要软链接一下
ln -s /usr/local/lib/node_modules/hexo-cli/bin/hexo /data/wwwroot/hexo
或者直接运行
hexo init
运行后会在你当前敲入命令的目录部署 hexo 代码,所以请确认好路径
随后清空缓存
hexo clean
生成静态
hexo g
hexo s

到此提示访问 URL 即可安装完毕

1.4 配置 Nginx

安装并部署 Nginx 有一点需要注意 root /root/hexos/public; 一定到部署 hexo 下级的 public
命令附录:

初始化:hexo init && npm install
生成博客:hexo g
部署博客:hexo d
清空缓存:hexo clean
启动本地服务器:hexo s
组合命令:hexo clean && hexo g -d

目录结构其下:

|
├── _config.yml            # 网站配置文件
├── .gitignore             # Git 忽略文件
├── node_modules           # 插件安装目录
├── package.json           # 描述插件
├── package-lock.json      # 描述插件 更详细
├── scaffolds              # 模板
├── source                 # 资源
└── themes                 # 主题

Hexo 配置项:

网站配置文件网站 配置文件:_config.yml ,官方配置文档传送门:配置 | Hexo
修改主题类型 配置文件:_config.yml 更改 theme: pure

1.5 美化 Hexo

这里我说明使用的模版主题为 icarus 当然可以选择 hexo 的主题列表挑选https://hexo.io/themes/

进入安装好的根目录/theme 下

git clone [https://github.com/ppoffice/hexo-theme-icarus.git](https://github.com/ppoffice/hexo-theme-icarus.git) themes/icarus

下载完成之后需要修改配置在 blog 文件夹下 _config.yml 文件 所有配置基本都在这里 找到 theme: landscape 修改为 theme: icarus 重启 hexo 服务即可

1.6 常见问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ hexo server
INFO =======================================
██╗ ██████╗ █████╗ ██████╗ ██╗ ██╗███████╗
██║██╔════╝██╔══██╗██╔══██╗██║ ██║██╔════╝
██║██║ ███████║██████╔╝██║ ██║███████╗
██║██║ ██╔══██║██╔══██╗██║ ██║╚════██║
██║╚██████╗██║ ██║██║ ██║╚██████╔╝███████║
╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
=============================================
INFO === Checking package dependencies ===
ERROR Package bulma-stylus is not installed.
ERROR Package hexo-component-inferno is not installed.
ERROR Package hexo-renderer-inferno is not installed.
ERROR Package inferno is not installed.
ERROR Package inferno-create-element is not installed.
ERROR Please install the missing dependencies your Hexo site root directory:
ERROR npm install --save bulma-stylus@0.8.0 hexo-component-inferno@^0.4.0 hexo-renderer-inferno@^0.1.3 inferno@^7.3.3 inferno-create-element@^7.3.3
ERROR or:
ERROR yarn add bulma-stylus@0.8.0 hexo-component-inferno@^0.4.0 hexo-renderer-inferno@^0.1.3 inferno@^7.3.3 inferno-create-element@^7.3.3

如图所示,依照提示 npm 安装依赖重新启动 hexo 服务即可

npm install --save bulma-stylus@0.8.0 hexo-component-inferno@^0.4.0 hexo-renderer-inferno@^0.1.3 inferno@^7.3.3 inferno-create-element@^7.3.3

当然外国网速不好可以选择 cnpm

附带配置项说明:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# Version of the Icarus theme that is currently used
version: 2.6.0
# 你的网站图标,可以搜索在线图标制作,并将其放在images文件夹中
favicon: /images/favicon.svg
# Additional HTML meta tags in an array.
meta:
# Path or URL to RSS atom.xml
rss: /atom.xml
# 显示在导航栏左侧的网站logo,同样可以自己制作
logo: /images/hxx.jpg
# Open Graph metadata
# https://hexo.io/docs/helpers.html#open-graph
open_graph:
# Facebook App ID
fb_app_id:
# Facebook Admin ID
fb_admins:
# Twitter ID
twitter_id:
# Twitter site
twitter_site:
# Google+ profile link
google_plus:
# Navigation bar link settings
navbar:
#菜单(显示名称:对应文件夹)
menu:
主页: /
归档: /archives
分类: /categories
标签: /tags
关于: /about
# 导航栏右侧图标链接
links:
My GitHub:
icon: fab fa-github
url: 'https://github.com/h2pl/'
# Footer section link settings
footer:
# 页脚图标链接
links:
Creative Commons:
icon: fab fa-creative-commons
url: 'https://creativecommons.org/'
Attribution 4.0 International:
icon: fab fa-creative-commons-by
url: 'https://creativecommons.org/licenses/by/4.0/'
Download on GitHub:
icon: fab fa-github
url: 'https://github.com/ppoffice/hexo-theme-icarus'
# 文章显示设置
article:
#代码主题atom-one-light亮色,atom-one-dark暗色
highlight:
# Code highlight themes
# https://github.com/highlightjs/highlight.js/tree/master/src/styles
theme: atom-one-dark
# Show code copying button
clipboard: true
# Default folding status of the code blocks. Can be "", "folded", "unfolded"
fold: unfolded
# 是否显示文章主图
thumbnail: true
# 是否显示估算阅读时间
readtime: true
# 搜索插件设置
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Search
search:
# Name of the search plugin
type: insight
# 评论插件设置
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment
comment:
#可选valine,disqus(科学上网)等
# Name of the comment plugin
avatar: retro # Gravatar style : mm/identicon/monsterid/wavatar/retro/hide
placeholder: 要不要说点啥... # Comment Box placeholder
type: valine
shortname: 黄小斜
# 打赏功能
# https://ppoffice.github.io/hexo-theme-icarus/categories/Donation/
donate:
-
# 阿里巴巴支付宝
type: alipay
# 二维码图片
qrcode: '/images/hxx.jpg'
-
# 微信
type: wechat
# 二维码图片
qrcode: '/images/hxx.jpg'

# 分享插件设置
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Share
share:
# Share plugin name
type: sharejs
# Sidebar settings.
# Please be noted that a sidebar is only visible when it has at least one widget
sidebar:
# 左侧边栏设置
left:
# 是否不随页面滚动
# https://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/make-a-sidebar-sticky-when-page-scrolls/
sticky: false
# right sidebar settings
right:
# 是否不随页面滚动
# https://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/make-a-sidebar-sticky-when-page-scrolls/
sticky: false
# 边栏小部件设置
# https://ppoffice.github.io/hexo-theme-icarus/categories/Widgets/
widgets:
-
# Widget name
type: profile
# Where should the widget be placed, left or right
position: left
# Author name to be shown in the profile widget
author: 黄小斜
# Title of the author to be shown in the profile widget
author_title: 蚂蚁金服Java工程师
# Author's current location to be shown in the profile widget
location: 浙江 杭州
# Path or URL to the avatar to be shown in the profile widget
avatar: /images/gzh.jpg
# Email address for the Gravatar to be shown in the profile widget
gravatar:
# Whether to show avatar image rounded or square
avatar_rounded: false
# 关注我的链接,可设为你的GitHub主页
follow_link: 'https://github.com/h2pl/'
# 个人介绍部件底部图标社交链接
social_links:
Github:
icon: fab fa-github
url: 'https://github.com/h2pl'
RSS:
icon: fas fa-rss
url: /
-
# Widget name
type: toc
# Where should the widget be placed, left or right
position: left
-
# Widget name
type: links
# Where should the widget be placed, left or right
position: left
# Links to be shown in the links widget
links:
CSDN: 'https://blog.csdn.net/a724888'
知乎: 'https://www.zhihu.com/people/h2pl/activities'
简书: 'https://www.zhihu.com/people/h2pl/activities'
-
# Widget name
type: category
# Where should the widget be placed, left or right
position: left
-
# Widget name
type: tagcloud
# Where should the widget be placed, left or right
position: left
-
# Widget name
type: recent_posts
# Where should the widget be placed, left or right
position: right
-
# Widget name
type: archive
# Where should the widget be placed, left or right
position: right
-
# Widget name
type: tag
# Where should the widget be placed, left or right
position: right
# Other plugin settings
plugins:
# Enable page animations
animejs: true
# Enable the lightGallery and Justified Gallery plugins
# https://ppoffice.github.io/hexo-theme-icarus/Plugins/General/gallery-plugin/
gallery: true
# Enable the Outdated Browser plugin
# http://outdatedbrowser.com/
outdated-browser: true
# Enable the MathJax plugin
# https://ppoffice.github.io/hexo-theme-icarus/Plugins/General/mathjax-plugin/
mathjax: true
# Show the back to top button on mobile devices
back-to-top: true
# Google Analytics plugin settings
# https://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Google-Analytics
google-analytics:
# Google Analytics tracking id
tracking_id:
# Baidu Analytics plugin settings
# https://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Baidu-Analytics
baidu-analytics:
# Baidu Analytics tracking id
tracking_id: 2289335dd443797b5867abbd156e7575
# Hotjar user feedback plugin
# https://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Hotjar
hotjar:
# Hotjar site id
site_id:
# Show a loading progress bar at top of the page
progressbar: true
# BuSuanZi site/page view counter
# https://busuanzi.ibruce.info
busuanzi: true
busuanzi:
enable: true
# CDN provider settings
# https://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/speed-up-your-site-with-custom-cdn/
# Show PV/UV of the website/page with busuanzi.
# Get more information on http://ibruce.info/2015/04/04/busuanzi/
busuanzi_count:
# count values only if the other configs are false
enable: true
# custom uv span for the whole site
site_uv: true
site_uv_header: 访客数
site_uv_footer: 人
# custom pv span for the whole site
site_pv: true
site_pv_header: 总访问量
site_pv_footer: 次
# custom pv span for one page only
page_pv: true
page_pv_header: <i class="fa fa-file-o"></i> 阅读数
page_pv_footer:

providers:
# Name or URL of the JavaScript and/or stylesheet CDN provider
cdn: jsdelivr
# Name or URL of the webfont CDN provider
fontcdn: google
# Name or URL of the webfont Icon CDN provider
iconcdn: fontawesome

使用Ghost-CLI安装Ghost1.x博客

Ghost 是一个现代化的,开源的,基于 Node.js 的博客发布平台,它的前端管理系统基于 Ember.js, 后端的模板引擎采用的 handlebars, 而默认数据库是 s、Sqlite3 或 MySQL,当然,你也可以使用其他类型的数据库。

Ghost Blog 介绍:

Ghost 是基于 Node.js 的开源博客平台,由前 WordPress UI 部门主管 John O’Nolan 和 WordPress 高级工程师(女) Hannah Wolfe 创立,目的是为了给用户提供一种更加纯粹的内容写作与发布平台。

先前提要:

本人安装的环境为:PHP+Apache+Nginx+Mysql+Node.js
安装的工具为:Yarn+RPM+Ghost-CLI
需要注意:官方 Ghost Blog 提议最少 VPS 需要 1G 运存,建议设置 SWAP

参考文章:

ghost 官方-Install & Setup (production)
ghost 官方-install
Yarn global
CentOS 7 安装配置 Ghost v1.x
Ubuntu16.04 安装 Ghost
Ghost 使用指南
Ghost 中文网

你的准备

**

准备要素

  • CentOS 7.3 64 位===官方推荐:Ubuntu
  • 默认数据库(Sqlite3)===笔者推荐:MYSQL
  • Nginx 1.14.0
  • Apache 2.4
  • Node.js7===Ghost 支持的 Node.js 的版本为 v8.9+, v6.9+, v4.5+
  • 服务器至少 1GB 内存(可以使用 Swap)
  • 需要一个非 root 的全权账号
  • Yarn 1.7.0
  • Ghost-CLI 1.8.1

这里介绍下两样东西 Yarm 以及 Ghost-CLI

Yarm

Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。

Yarn 是一个依赖管理工具。它能够管理你的代码,并与全世界的开发者分享代码。Yarn 是高效、安全和可靠的,你完全可以安心使用。

Yarn 能够让你使用其他开发者开发的代码,让你更容易的开发软件。如果你在使用中发现任何问题,欢迎发 issue 或者贡献代码,一旦问题被修复,你就可以继续使用 Yarn 战斗了。
代码是通过包(有时也被称为模块)进行共享的。 在每一个包中包含了所有需要共享的代码,另外还定义了一个 package.json 文件,用来描述这个包。

特色:简单来说比 RPM/NPM 安装东西快捷多了

Ghost-CLI

Ghost CLI 项目的目标是为不想使用 Ghost(Pro)的人尽可能简单地设置和维护 Ghost 站点。

Ghost-CLI 针对的是那些在命令行环境中感觉舒适的人,因此会有一些技术知识。Ghost CLI 的设计目标是通过单一命令安装或更新 Ghost。

为了使这些目标能够通过 Ghost 的小团队获得和维护,我们推荐 Ghost-CLI 使用的推荐系统栈以及最少的配置选项。

特色:

  1. 快捷安装
  2. 自动配置
  3. 快速启动/停止/重启/再配置 Ghost
  4. 版本升级
  5. 自检错误

配置内存

内存问题是首要问题,若你的服务器剩余内存使用量>1000M 请跳过这步骤!

这里 VPS 可以通过探针来查看内存占用情况
云服务器通过自家云端查看内存占用情况

若您的 Ubuntu 服务器运存不太理想,可以查看这篇文章:https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-16-04

物理拓展

如果可以用钱解决的问题那不是问题。

免费的 Swap 拓展

Swap 分区的用处是当物理内存不够用的时候,系统会把数据放到 swap 中,所以 swap 起到了一个虚拟内存的作用。Ghost 需要至少 1GB 物理内存,否则会报错,可以通过设置 swap 分区解决

1.查看主机物理内存和虚拟内存:

free

2.在 /var/swap 创建 1024k 个 1k 大小的空文件:

dd if=/dev/zero of=/var/swap bs=1k count=1024k

3.创建 swap 分区:

mkswap /var/swap

4.启用 swap 分区:

swapon /var/swap

5.写入分区信息:

echo '/var/swap swap swap default 0 0' >> /etc/fstab

6.再次查看 Swap 分区大小:

free
or
探针/云服务器 plug-in

配置 Node.js

先上个两个指令检验是否安装和加载
node -v

which node

  1. 第一个是查看版本号
  2. 第二个是查看安装配置位置,其他软件也是类似(exp. which tomcat)

全新安装的情况下,有很多方法 wegt/npm 不等,选择自己喜欢

下载 Node.js

curl --silent --location [https://rpm.nodesource.com/setup_8.x](https://rpm.nodesource.com/setup_8.x) | bash -

安装 Node.js

yum install -y nodejs

测试是否安装成功

惯例
node -v


建议一步到位 8.9+

前提你拥有 node.js
安装依赖的 N 模块
npm install -g n

升级 node.js 到最新稳定版或者指定版本

n stable
or 我正在使用的版本
n v8.11.1

!注意:

Node.js 需要安装在系统路径,比如 /usr/bin/node 或者 /usr/local/bin/node 等。不推荐使用 nvm 来管理 node.js,nvm 会把 node.js 安装在 /root 或者 /home 等用户路径,之后你还需要链接等等操作
_

配置 Yarn

1.在 CentOS、Fedora 和 RHEL 操作系统中,你可以通过我们的 RPM 包仓库来安装 Yarn。

sudo wget [https://dl.yarnpkg.com/rpm/yarn.repo](https://dl.yarnpkg.com/rpm/yarn.repo) -O /etc/yum.repos.d/yarn.repo

2.执行安装

sudo yum install yarn

3.测试是否安装成功

yarn --version

4.查看 Yarn 使用的源

yarn config get registry

5.如果不是 taobao 或者 cnpm 的源,推荐阿里巴巴

yarn config set registry [https://registry.npm.taobao.org/](https://registry.npm.taobao.org/)

6.检查 Yarn 全局的 bin 路径

yarn global bin


!注意:

一定要检查是否在/usr/local/bin 里面否则需要$PATH 和更改全局 bin 路径因为必需确保 Yarn 的全局 bin 路径在一个公共的位置,因为之后的操作 ghost 不能使用 root 账号,需要另开一个账号,权限问题值得注意。因为必需确保 Yarn 的全局 bin 路径在一个公共的位置,因为之后的操作 ghost 不能使用 root 账号,需要另开一个账号,权限问题值得注意。

修改 Yarn 全局的 bin 路径

比如要将路径改到 /usr/local/bin 位置:

yarn config set prefix /usr/local

再次查看 Yarn 全局的 bin 路径:

yarn global bin

安装数据库和 Nginx

1.查看 MySQL 版本

mysqld -V

2.查看 MySQL 服务

systemctl is-active mysqld

如何安装 mysql 请自行 bing


1.查看 Nginx 版本

nginx -v

2.检查 Nginx 服务是否正在运行

systemctl is-active nginx

如何安装 nginx 请自行 bing

  • 值得注意的是:我们在配置 Nginx 的时候,如果是二级域名记得需要 DNS 如果用了加速记得 CDN/DNS 要结合好。同时在调教 Nginx 时候,做伪静态化和防盗链不要指向单一 index.php/index.html 以及 JS 文件/CSS 文件/PNG 图片等文件是死亡周期等要配置好,这里做一个提醒后续会补充说明到。

_

安装 Ghost-CLI

1.使用 Yarn 全局安装

yarn global add ghost-cli

2.查看安装的 ghost-cli 版本并证实是否成功安装

ghost -v

配置新角色

创建一个新的用户以解决安装 ghost blog 的要求,如果你拥有非 root 账号可以跳过。


1.创建新用户

adduser kaiccomic

kaiccomic 是我建立起的新账户名字

2.设置用户密码

passwd kaiccomic

密码要求:

  • 不可以与用户名一致
  • 不可以低于 8 位
  • 不可以存在于非安全的数据字典密码

输入两遍用户密码后进行第三步

3.更改 sudoers 超级权限文件的只读权限

chmod -v u+w /etc/sudoers

4.编辑

vi /etc/sudoers

然后找到这一行

Next comes the main part: which users can run what software on

which machines (the sudoers file can be shared between multiple

systems).

Syntax:

user    MACHINE=COMMANDS

The COMMANDS section may have other options added to it.

Allow root to run any commands anywhere

root    ALL=(ALL)       ALL

1
2
3
4
5
6
## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL

在 root ALL=(ALL) ALL 下加入

kaiccomic ALL=(ALL) NOPASSWD:ALL

修改完毕后
键盘按下“ESC”键入,结束修改
并且输入
:wq保存并退出
OR
:q!强制关闭并退出

5.保存退出,并恢复 sudoers 超级权限文件的只读文件权限

chmod -v u-w /etc/sudoers

以防攻击

6.切换用户身份

su root

一键安装 Ghost

至此,我们已经完成了百分之 90 安装进度了,剩下就是一键安装类似脚本一样的安装方式了。


1.新建网站根目录

mkdir -p /data/wwwroot/blog.xxx.com

2.赋予该文件夹指定用户操作权限

chown kaiccomic:kaiccomic /data/wwwroot/blog.xxx.com

3.更改该文件夹权限

chmod 775 /data/wwwroot/blog.xxx.com

4.进入该文件夹

cd /data/wwwroot/blog.xxx.com

5.切换非 root 用户


这里开始正式安装 Ghost,这里提供两种方式安装。

第一种安装方法:

默认使用 Sqlite3 作为数据库安装指令

ghost install --no-stack --db sqlite3

enter 回车便开始自检安装环境

1
2
3
4
5
6
7
8
9
✔ Checking system Node.js version
✔ Checking logged in user
✔ Checking current folder permissions
ℹ Checking operating system compatibility [skipped]
✔ Checking memory availability
✔ Checking for latest Ghost version
✔ Setting up install directory
✔ Downloading and installing Ghost v1.24.5
✔ Finishing install process

若自检发现
出现 X 叉号即为问题所在,问题会以 message+error 文件形式供大家查看,纯英文很容易得出解决方法
出现 Shipped 则为跳过此步骤,大多表示建议性或不重要的注意性
看不懂英文可以翻译

完成自检无错误后开始操作

  • 第一操作步骤
    Enter your blog URL?
    输入您的博客 URL 地址,这里输入 http/https 都可以
    [https://blog.xxx.com](https://blog.xxx.com)
    Enter 回车
  • 第二操作步骤
    Do you wish to set up Nginx
    是否自动配置 Nginx 服务
    y
    这里会发现报 Shipped 跳过,因为 Ghost-CLI 在 CentOS 上会不识别已安装的 Nginx,稍后我们自己手动设置
    Enter 回车
  • 第三操作步骤
    Do you wish to set up Systemd?
    是否接下来自动完成系统配置
    y
    Enter 回车
  • 第四操作步骤
    Do you want to start Ghost?
    是否接下来立刻启动 Ghost
    n
    我们需要稍后启动,完成 Nginx 设置,启动也是会报错,无用功
    Enter 回车

第二种安装方法:

使用 MySQL 作为数据库安装指令

ghost install --no-stack

enter 回车便开始自检安装环境

1
2
3
4
5
6
7
8
9
10
✔ Checking system Node.js version
✔ Checking logged in user
✔ Checking current folder permissions
ℹ Checking operating system compatibility [skipped]
✔ Checking for a MySQL installation
✔ Checking memory availability
✔ Checking for latest Ghost version
✔ Setting up install directory
✔ Downloading and installing Ghost v1.24.5
✔ Finishing install process

完成自检无错误后开始操作

  • 第一操作步骤
    Enter your blog URL?
    输入您的博客 URL 地址,这里输入 http/https 都可以
    [https://blog.xxx.com](https://blog.xxx.com)
    Enter 回车
  • 第二操作步骤
    Enter your MySQL hostname:
    输入 MySQL 的登陆地址,本机登陆就是 localhost 直接回车即可,非本机记得带端口,也可以键入
    localhost
    Enter 回车
  • 第三操作步骤
    Enter your MySQL username:
    输入 MySQL 的登陆用户名
    xxxxxx
    Enter 回车
  • 第四操作步骤
    Enter your MySQL password: [input is hidden]
    输入 MySQL 的登陆口令密码,输入会隐藏请不要输错
    xxx
    Enter 回车
  • 第五操作步骤
    Enter your Ghost database name: (blog_imzhengfei_com_prod)
    输入 MySQL 的数据库名,需要提前创建好!默认 blog_imzhengfei_com_prod 不更改请直接 Enter 回车,或者
    blog_imzhengfei_com_prod
    Enter 回车
  • 第六操作步骤
    Do you wish to set up "ghost" mysql user?
    是否针对 ghost 建立一个新的访问用户,可以不需要
    n
    Enter 回车
  • 第七操作步骤
    Do you wish to set up Nginx
    是否自动配置 Nginx 服务
    y
    这里会发现报 Shipped 跳过,依旧是因为 Ghost-CLI 在 CentOS 上会不识别已安装的 Nginx,稍后我们自己手动设置
    Enter 回车
  • 第八操作步骤
    Do you wish to set up Systemd?
    是否接下来自动完成系统配置
    y
    Enter 回车
  • 第九操作步骤
    Do you want to start Ghost?
    是否接下来立刻启动 Ghost
    n
    我们需要稍后启动,完成 Nginx 设置,启动也是会报错,无用功
    Enter 回车

配置 Nginx

1.找到 Conf 配置文件

cd /usr/local/nginx/conf/vhost
值得注意这里我是使用了二级域名部署 Ghost 所以存放在 vhost 下,若是一级目录,一般存放在/usr/local/nginx/conf/下

2.修改文件

vi /usr/local/nginx/conf/vhost/blog.xxx.com

3.修改并写入

编辑代码
键盘按下“i”键入,开始修改

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
server {
listen 80;
listen 443 ssl spdy;
ssl_certificate /usr/local/nginx/conf/ssl/blog.xxx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/blog.xxx.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+xxx!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server_name blog.xxx.com bk.xxx.com;
access_log /data/wwwlogs/blog.xxx.com_nginx.log combined;
root /data/wwwroot/blog.xxx.com;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

以上我们需要加入的是这些东西,其余的 SSL 是安全证书的声明以及 log 文件的声明,这里我添加了两个域名

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name blog.xxx.com bk.xxx.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:2368;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

多个请用域名空格隔开,不用加 HTTP/HTTPS
发现 404 NOT FOUND nginx 错误一定是配置文件出错。

修改完毕后
键盘按下“ESC”键入,结束修改
并且输入
:wq保存并退出

4.重启 Nginx 服务

service nginx restart
systemctl restart nginx

测试 Ghost

至此 Ghost 安装已经完毕,开始测试。测试之前需要注意的地方是,不可以进入网站根目录键入 ghost start 进行启动,因为系统是 CentOS 关系。我们可以另寻出路进行 Ghost 的启动。


1.寻址 Ghost 服务

cd /usr/lib/systemd/system/

进入 CentOS 系统的 systemctl 服务主体存贮目录即可查看

ghost_blog-xxx-com.service

带 ghost 即是我们需要的服务,复制粘贴

2.访问 Ghost 测试服务

systemctl start ghost_blog-xxx-com.service

3.查看 Ghost 服务状态

systemctl status ghost_blog-xxx-com.service

看到以下的提示带绿灯
Active: active (running)

!再次注意:
不要使用 ghost start 启动,该命令在 CentOS 系统上会因为服务检查返回值为 unknown 而出错,无用功

4.浏览器访问

访问该域名 https://blog.xxx.com 看到博客页面即表示成功博客安装启动成功!
进入 https://blog.xxx.com/ghost 可以看到后台,并且完成第一次使用的注册和浏览说明书

接下来可以配置开机启动以免后顾之忧

systemctl enable ghost_blog-imzhengfei-com

若需要临时结束可以敲入以下指令
systemctl stop ghost_blog-xxx-com.service

顺带提供操作 Ghost 的几个常用指令

!注意:
操作 Ghost 需要非 root 账户,所以需要加 Sudo 权限加指令。

重新设置 Ghost
sudo ghost config

启动 Ghost
sudo ghost start

重启 Ghost
sudo ghost restart

停止 Ghost
sudo ghost stop

更新 Ghost
sudo ghost update

结语 — 问题解决方案

Q1 暂无


更多问题咨询请留言,有幸看到即回复 Thx

Oracle 学习笔记

查询及删除重复记录的 SQL 语句

一、查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断
select * from 表 where Id in (select Id from 表 group byId having count(Id) > 1)

二、删除表中多余的重复记录,重复记录是根据单个字段(Id)来判断,只留有 rowid 最小的记录
DELETE from 表 WHERE (id) IN ( SELECT id FROM 表 GROUP BY id HAVING COUNT(id) > 1) AND ROWID NOT IN (SELECT MIN(ROWID) FROM 表 GROUP BY id HAVING COUNT(*) > 1);

三、查找表中多余的重复记录(多个字段)
select _from 表 a where (a.Id,a.seq) in(select Id,seq from 表 group by Id,seq having count(_) > 1)

四、删除表中多余的重复记录(多个字段),只留有 rowid 最小的记录
delete from 表 a where (a.Id,a.seq) in (select Id,seq from 表 group by Id,seq having count(_) > 1) and rowid not in (select min(rowid) from 表 group by Id,seq having count(_)>1)

五、查找表中多余的重复记录(多个字段),不包含 rowid 最小的记录
select _from 表 a where (a.Id,a.seq) in (select Id,seq from 表 group by Id,seq having count(_) > 1) and rowid not in (select min(rowid) from 表 group by Id,seq having count(*)>1)

关于hexo icarus主题定制化

1 - 添加天气组件

使用 心知天气 API 即可

1
2
3
<a class="navbar-item">
<div id="tp-weather-widget"></div>
</a>
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
36
37
38
39
(function (a, h, g, f, e, d, c, b) {
b = function () {
d = h.createElement(g);
c = h.getElementsByTagName(g)[0];
d.src = e;
d.charset = "utf-8";
d.async = 1;
c.parentNode.insertBefore(d, c);
};
a["SeniverseWeatherWidgetObject"] = f;
a[f] ||
(a[f] = function () {
(a[f].q = a[f].q || []).push(arguments);
});
a[f].l = +new Date();
if (a.attachEvent) {
a.attachEvent("onload", b);
} else {
a.addEventListener("load", b, false);
}
})(
window,
document,
"script",
"SeniverseWeatherWidget",
"//cdn.sencdn.com/widget2/static/js/bundle.js?t=" +
parseInt((new Date().getTime() / 100000000).toString(), 10)
);
window.SeniverseWeatherWidget("show", {
flavor: "slim",
location: "WX4FBXXFKE4F",
geolocation: true,
language: "en",
unit: "c",
theme: "light",
token: "ebb2adc5-xxxx-xxxx-xxxx-7e7102ba8185",
hover: "disabled",
container: "tp-weather-widget",
});

注意夜间模式样式冲突

2 - 解锁 RSS 功能

  • 进入本地 hexo 根目录键入npm install hexo-generator-feed
  • 更改访问路径rss: /atom.xml
  • clean & g重启服务即可

3 - 解锁邮件订阅功能

Icarus 的邮件订阅功能由 Google Feedburner 提供。 按照如下步骤即可启用此插件:

  1. 首先,你要完成第二步骤,确认你的 Hexo 网站的 RSS 源正常。
  2. 然后登录Google Feedburner,在输入框内输入你的 RSS 地址并点击“下一步”(Next) 来添加你的 RSS 源。
  3. 然后,在下一页中填写“源标题”。 点击“下一步”(Next)来继续自定义你的源,或者点击“直接跳到源管理”(Skip directly to feed management)来完成配置。
  4. 完成添加源后,点击网页顶部的”我的源“(My Feeds)链接。 点击“我的源”(My Feeds)页面上新添加的源。
  5. 切换到”宣传“(Publicize)标签页并点击页面左侧的”邮件订阅“(Email Subscription)链接。 点击“激活”(Activate)按钮来开启“邮件订阅”(Email Subscription)功能。
  6. 在”邮件订阅“(Email Subscription)页面上从 HTML 代码中找到如下信息:

    来自 Google Feedburner URL:https://feedburner.google.com/fb/a/mailverify?uri=**


然后复制uri=后的 ID(如feedforall/ABCD)到挂件配置的feedburner_id设置中,_config.yml 设置示例如下

1
2
3
4
5
6
7
widgets:
-
position: left
type: subscribe_email
# (可选) 描述文字
description: 邮件订阅,更新早知道
feedburner_id: feedforall/ABCD

4 - 解锁 Google 广告收入

Google AdSense上新建广告。 然后,复制广告 HTML 代码中的data-ad-clientdata-ad-slot值分别填入到挂件配置的client_idslot_id项中,_config.yml 设置示例如下

1
2
3
4
5
6
widgets:
-
position: left
type: adsense
client_id: ca-pub-xxxxxxxx
slot_id: xxxxxxx

5 - 解锁分享功能

_config.yml 设置中的 share 的 type 更改为sharejs
在 icarus 主题下还提供以下几种分享:
AddThis AddToAny Baidu Share Share.js ShareThis
具体详情可以分别查看官方文档。

6 - 添加一言/今日诗词

浏览一言今日诗词的对接文档添加到相应到头部、尾部或 weight 即可。
这里列举一个引用一言的方法:

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
<p id="hitokoto">:D 获取中...</p>
<!-- 以下写法,选取一种即可 -->
<!-- 现代写法,推荐 -->
<!-- 兼容低版本浏览器 (包括 IE),可移除 -->
<script src=https://cdn.jsdelivr.net/npm/bluebird@3/js/browser/bluebird.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js></script>
<!--End-->
<script>
fetch('https://v1.hitokoto.cn')
.then(function (res){
return res.json();
})
.then(function (data) {
var hitokoto = document.getElementById('hitokoto');
hitokoto.innerText = data.hitokoto;
})
.catch(function (err) {
console.error(err);
})
</script>
<!-- 老式写法,兼容性最忧 -->
<script>
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://v1.hitokoto.cn');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var data = JSON.parse(xhr.responseText);
var hitokoto = document.getElementById('hitokoto');
hitokoto.innerText = data.hitokoto;
}
}
xhr.send();
</script>
<!-- 新 API 方法, 十分简洁 -->
<script src="https://v1.hitokoto.cn/?encode=js&select=%23hitokoto" defer=""></script>

7 - 夜间模式

Hexo 主题 icarus 配置夜间模式 Night Mode

写在最后

更多的功能解锁可以查阅 来自官方的插件功能,其包含画廊、TEX/MathJax 数学公式显示、浏览器升级提醒和网页载入动画等。

使 hexo icarus 主题支持拼音搜索

:::success
在最新的 5.0 版本已经支持拼音搜索,请升级体验


本篇文章直击如何使到 icarus 升级到可以支持拼音搜索

前期准备

  • Icarus 主题版本 3.0 以上
  • 搜索插件使用的是 Insight

操作方法

  1. 另存为下面的文件到  themes/icarus/source/js

pinyin.js

  1. 另存为下面的文件到  themes/icarus/layout/search

insight.jsx

  1. 另存为下面的文件到  themes/icarus/source/js

insight.js


  1. 修改  themes/icarus/layout/search/insight.jsx,加入拼音检索开关和依赖的 pinyin.js
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
/**
* Insight search plugin JSX component.
* @module view/search/insight
*/
--- a/src/view/search/insight.jsx
+++ b/src/view/search/insight.jsx
@@ -3,7 +3,7 @@
const { Component, Fragment } = require('inferno');
-const { cacheComponent } = require('../../util/cache');
+const { cacheComponent } = require('hexo-component-inferno/lib/util/cache');

/**
* Algolia search engine JSX component.
@@ -36,11 +36,18 @@ class Insight extends Component {
<div class="searchbox-input-container">
<input type="text" class="searchbox-input" placeholder={translation.hint}/>
</div>
+ <div class="searchbox-pinyin">
+ <label class="checkbox">
+ <input id="search-by-pinyin" type="checkbox" checked="checked"/>
+ <span> 拼音检索</span>
+ </label>
+ </div>
<a class="searchbox-close" href="javascript:;">×</a>
</div>
<div class="searchbox-body"></div>
</div>
</div>
+ <script src="/js/pinyin.js" defer={true}></script>
<script src={jsUrl} defer={true}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
  1. 修改  themes/icarus/source/js/insight.js,在原有匹配代码基础上增加拼音匹配代码
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
diff --git a/asset/js/insight.js b/asset/js/insight.js
index 33150b3..205a096 100644
--- a/asset/js/insight.js
+++ b/asset/js/insight.js
@@ -6,6 +6,19 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
const $main = $('.searchbox');
const $input = $main.find('.searchbox-input');
const $container = $main.find('.searchbox-body');
+ const $searchByPinyin = $main.find('#search-by-pinyin');
+
+ /**
+ * 查询匹配拼音的数据。性能低于普通匹配,如果未启用拼音检索模式,直接返回 false。
+ * https://github.com/xmflswood/pinyin-match
+ * @param input {string} 目标字符串
+ * @param keyword {string} 输入的拼音或其他关键词
+ * @returns {[Array]|{Boolean}} 找到返回出现位置,未找到 / 未启用返回 false
+ */
+ function pinyinMatch(input, keyword) {
+ if (!$searchByPinyin.prop("checked")) return false;
+ return PinyinMatch.match(input, keyword);
+ }

function section(title) {
return $('<section>').addClass('searchbox-result-section').append($('<header>').text(title));
@@ -33,10 +46,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
const testText = text.toLowerCase();
const indices = matches.map(match => {
const index = testText.indexOf(match.toLowerCase());
- if (!match || index === -1) {
- return null;
+ if (match && index !== -1) {
+ return [index, index + match.length];
}
- return [index, index + match.length];
+ // Search by pinyin
+ const pinyinIndex = pinyinMatch(testText, match.toLowerCase());
+ return pinyinIndex ? [pinyinIndex[0], pinyinIndex[1] + 1] : null;
}).filter(match => {
return match !== null;
}).sort((a, b) => {
@@ -140,6 +155,8 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
}
if (obj[field].toLowerCase().indexOf(keyword) > -1) {
return true;
+ } else if (pinyinMatch(obj[field].toLowerCase(), keyword)) {
+ return true;
}
return false;
});
@@ -266,10 +283,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
if (location.hash.trim() === '#insight-search') {
$main.addClass('show');
}
- $input.on('input', function() {
- const keywords = $(this).val();
+ function onInputChange() {
+ const keywords = $input.val();
searchResultToDOM(keywords, search(json, keywords));
- });
+ }
+ $input.on('input', onInputChange);
+ $searchByPinyin.on('change', onInputChange);
$input.trigger('input');
});
  1. 修改  themes/icarus/include/style/search.styl,调整拼音检索复选框大小和位置
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
diff --git a/include/style/search.styl b/include/style/search.styl
index 0cdedd9..02d9b5e 100644
--- a/include/style/search.styl
+++ b/include/style/search.styl
@@ -96,6 +96,16 @@ $searchbox-bg-pagination-item-disabled ?= $searchbox-bg-container
.searchbox-input
flex-grow: 1
color: inherit
box-sizing: border-box
padding: .75em 0 .75em 1.25em
background: $searchbox-bg-input

+ .searchbox-pinyin
+ display: flex
+ align-items: center
+ user-select: none
+ input
+ vertical-align: middle
+ span
+ position: relative
+ top: 1px
+
.searchbox-close
display: inline-block
font-size: 1.5em
padding: .5em .75em
cursor: pointer

致谢

感谢来自 ppoffice 的hexo-component-inferno 项目
以及 xmflswood 的  pinyin-match 项目提供支撑

MySQL数据库跨服务器数据同步

1.环境说明

MySQL 版本:5.7.20

本地数据库 A(作为 Zentao 数据库),本地数据库 B,本地程序 C;本地为 Windows 环境。

2.方案探索

方案 1:在 A 中写触发器,表中数据变化时将 ID 发给 C,由 C 在 A 中查询变化的数据,写入 B。过程中需要安装 mysql-udf-http 插件

(参考:https://www.2cto.com/database/201801/713571.html)

方案 2

在 A 中用触发器监控数据的变化,然后调用存储过程将数据推送给 B ,用 BDlink 进行数据库跨库。

DBlink 是 oracle 进行跨库访问的方法,SQL Server 可以用 linkServer。在 mysql5.0 版本以上,可以采用 FEDERATED 引擎(默认引擎为 InnoDB)。

(参考:https://blog.csdn.net/langkeziju/article/details/50462943)

所以值得注意:建表时指定引擎为 FEDERATED

ENGINE=FEDERATED CONNECTION='mysql://user:password@ip:port/test1/test_table';

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE federated_table (
id int(20) NOT NULL auto_increment,
name varchar(32) NOT NULL default '',
age varchar(4) NOT NULL default '0',
sts char(1) NOT NULL default '0',
office VARCHAR(64) NOT NULL default '0',
telephone VARCHAR(15) NOT NULL default '0',
PRIMARY KEY (id),
KEY name (name),
KEY age (age),
KEY sts (sts),
KEY telephone (telephone),
KEY office (office)

) ENGINE=FEDERATED CONNECTION='mysql://user:password@ip:port/test1/test_table';

前提条件是可以访问远程数据库,配置好读写权限,mysql 开启 FEDERATED 引擎。

建完后本地数据与远程数据一样,进行 curd 操作都可同步。

既然通过 FEDERATED 可以将数据同步过来,那么可以在 B 中建立 A 的映射。

因为映射表在程序 C 中并没有实际意义,需要将映射表的某些字段与 B 实际业务表的数据进行同步,可以采用 程序进行操作 或者 利用触发器和存储过程。

触发器示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
drop TRIGGER updateFromFed; #删除触发器,建立后需要删除才能修改


delimiter $$ #修改语句结束标志为$$
create TRIGGER insertFromFederated AFTER INSERT
on federated_table for each ROW
begin #状态=1执行插入操作
DECLARE de VARCHAR(128);
set de = CONCAT(IFNULL(new.name,''),'-',IFNULL(new.age,''),'-',IFNULL(new.office,''));
if new.sts="1" THEN

INSERT into local1(id,name,description,sts)
values (new.id,new.name,de,new.sts);
INSERT into local2(id,name,office,sts)
values (new.id,de,new.office,new.sts);
END IF;
END $$
delimiter ;

参考:https://blog.csdn.net/qq_33556185/article/details/77745449

存储过程示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#mysql 下面的例子在把select into 的ID写死的时候设置参数值为空,但是在使用传进来的ID作为参数时设置参数值不为空。
show create procedure test;#查看
CALL test();#调用
drop procedure if exists test;#删除
in id VARCHAR(32)
delimiter $$
create PROCEDURE test()
begin
DECLARE id VARCHAR(32);
set id='8302';
DECLARE v_name VARCHAR(128)

SELECT local2.name INTO v_name from local2 where id = 5;
select id,v_name;
#INSERT into local2(id,name,office,sts) VALUES (id,des,'办公室','8');
end $$
delimiter ;

show engines;

参考:http://www.shouce.ren/api/view/a/11695

MySQL安装Federated引擎

Beginning with MySQL 5.0.64, the FEDERATED storage engine is not enabled by default in the running server; to enable FEDERATED, you must start the MySQL server binary using the –federated option.

从 mysql 官方文档可以看出, 从 5.0.64 以后 Federated 存储引擎默认不开启, 但我们需要使用的时候, 需要手动开启

mysql> show engines;

显示 FEDERATED 的 Support 为 NO 即没有安装

键入开始安装

mysql> install plugin federated soname 'ha_federated.so';

配置文件开启

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vi /etc/my.cnf

#*******************************************************#
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
federated # 指定开启

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
#*******************************************************#

启动服务

mysqld --federated

重启服务

service mysqld restart

再查看服务是否开启

mysql> show engines;

使用模拟器调试移动端

使用 weinre 等代理服务器

1.安装需要 Node.js 平台, 先安装好后, 打开 Node.js command prompt, 通过 NPM 来安装 weinre
npm -g install weinre 2.命令启动 weinre
weinre -httpPort 8081 -boundHost -all- 3.脚本附着对象页面
<script src="http://ipsource:8081/target/target-script-min.js#anonymous"></script> 4.点击 weinre Access Points 即可开箱调试

使用 chrome://inspect/#devices 调试

安卓手机(部分华为手机除外)可以通过 USB 连接电脑,开启调试功能,在浏览器中输入 chrome://inspect/#devices 进行调试;
苹果手机则需要调用 macos 的 safari 浏览器进行调试。

使用 vide 调试

待补充。