LookPHP https://www.gravatar.com/avatar/4e728b1b244070a1005da09d25d0faf3 2018-12-11T16:03:56.201Z https://lookphp.github.io/ lookphp [email protected] Hexo 如何将 Github 上的仓库导入 CODING https://lookphp.github.io/2018/12/11/如何将-Github-上的仓库导入-CODING/ 2018-12-11T15:24:00.000Z 2018-12-11T16:03:56.201Z <![CDATA[

在 CODING 中新建项目

在 CODING 中新建一个同名项目,不选择 启用 README.md 文件初始化项目,以及任何 License 和 .gitignore 文件。

image
image

克隆 Github 上的项目

将 Github 上想要导入的项目完整克隆到本地。

image
image

本地执行克隆命令,并带上参数 --bare
git clone https://github.com/antirez/redis.git --bare

image
image

将克隆下来的仓库推送到 CODING

克隆完成后,将仓库推送到 CODING 上。
使用仓库页面提供的 URL。

image
image

推送所有的分支和对象,向coding推送时,需要添加参数 --all

1
2
3
cd redis.git

git push https://git.coding.net/jiong/redis.git --all

image
image

完成后,再执行推送所有的标签的命令,带参数 --tag
git push https://git.coding.net/jiong/redis.git --tags

image
image
image
image

这样,整个仓库就全部导入到 CODING 中了。

参考文档

]]> <h1 id="在-CODING-中新建项目"><a href="#在-CODING-中新建项目" class="headerlink" title="在 CODING 中新建项目"></a>在 CODING 中新建项目</h1><p>在 CODING 中新建一个同名项目,不选择 在 Oracle 中实现自增ID https://lookphp.github.io/2018/12/06/在-Oracle-中实现自增ID/ 2018-12-06T15:39:11.000Z 2018-12-11T15:52:06.192Z <![CDATA[

如果你经常使用 MySQL,你肯定对 AUTO_INCREMENT 非常熟悉,因为经常要用到它。

一、什么是自增列?

自增列是数据库中值随插入的每个行自动增加的一列。它最常用于主键或 ID 字段,这样每次增加一行时,不用指该字段的值,它就会自动增加,而且是唯一的。

当在 MySQL 中定义列时,我们可以指定一个名为 AUTO_INCREMENT 的参数。然后,每当将新值插入此表中时,放入此列的值比最后一个值加 1。

但很不幸,Oracle 没有 AUTO_INCREMENT 功能。 那要如何在Oracle中做到这一点呢?

二、在 Oracle 11g 中设置自增字段

创建表

首先创建一张用于测试的表:

1
2
3
4
CREATE TABLE "TEST" (
ID NUMBER(11) PRIMARY KEY,
NAME VARCHAR2(50BYTE) NOT NULL
);

创建序列

然后创建一个名为 TEST_ID_SEQ 的序列(序列名称自己随意设定):

1
2
3
4
5
6
CREATE SEQUENCE TEST_ID_SEQ
INCREMENT BY 1
START WITH 100
MAXVALUE 999999999
NOCYCLE
NOCACHE;

如果要删除序列,可以使用下面的 SQL 命令:

1
DROP SEQUENCE TEST_ID_SEQ;

对 SEQUENCE 的一些说明:

  • INCREMENT BY 用于指定序列增量(默认值:1),如果指定的是正整数,则序列号自动递增,如果指定的是负数,则自动递减。
  • START WITH 用于指定序列生成器生成的第一个序列号,当序列号顺序递增时默认值为序列号的最小值,当序列号顺序递减时默认值为序列号的最大值。
  • MAXVALUE 用于指定序列生成器可以生成的组大序列号(必须大于或等于 START WITH,并且必须大于 MINVALUE),默认为 NOMAXVALUE。
  • MINVALUE 用于指定序列生成器可以生成的最小序列号(必须小于或等于 START WITH,并且必须小于 MAXVALUE),默认值为 NOMINVALUE。
  • CYCLE 用于指定在达到序列的最大值或最小值之后是否继续生成序列号,默认为 NOCYCLE。
  • CACHE 用于指定在内存中可以预分配的序列号个数(默认值:20)。

到这一步其实就已经可以实现字段自增,只要插入的时候,将 ID 的值设置为序列的下一个值 TEST_ID_SEQ.NEXTVAL 就可以了:

1
2
3
4
5
6
7
8
9
10
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name1');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name2');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (TEST_ID_SEQ.NEXTVAL, 'name3');
SQL> SELECT * FROM "TEST";

ID NAME
--- ------
100 name1
101 name2
102 name3

为了简化插入操作,我们还可以创建一个触发器,当将数据插入到 “TEST” 表的时候,自动将最新的 ID 插入进去。

创建触发器

1
2
3
4
5
6
7
8
9
CREATE OR REPLACE TRIGGER TEST_ID_SEQ_TRG
BEFORE INSERT ON "TEST"
FOR EACH ROW
WHEN (NEW."ID" IS NULL)
BEGIN
SELECT TEST_ID_SEQ.NEXTVAL
INTO :NEW."ID"
FROM DUAL;
END;

这样的话,每次写插入语句,只需要将 ID 字段的值设置为 NULL 它就会自动递增了:

1
2
3
4
5
6
7
8
9
10
11
12
13
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name4');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name5');
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name6');
SQL> SELECT * FROM "TEST";

ID NAME
--- ------
100 name1
101 name2
102 name3
103 name4
104 name5
105 name6

一些值得注意的地方

插入指定 ID

如果某条插入语句指定了 ID 的值如:

1
2
3
4
5
6
7
8
9
10
11
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (1000, 'name1001');
SQL> SELECT * FROM "TEST";

ID NAME
--- ------
100 name1
101 name2
102 name3
103 name4
104 name5
1000 name1001

那么下次 ID 还是会在原来的基础上继续增加:

1
2
3
4
5
6
7
8
9
10
11
SQL> INSERT INTO "TEST" ("ID", "NAME") VALUES (NULL, 'name1001');
SQL> SELECT * FROM "TEST";

ID NAME
--- ------
100 name1
101 name2
102 name3
103 name4
104 name5
1000 name1001

但当序列的值到了 1000 的时候,如果 ID 允许重复,就会有两行记录 ID 都为 1000。

但如果 ID 设置为了主键,如本文的例子 ID NUMBER(11) PRIMARY KEY,则插入就会报错:

1
Error : ORA-00001: unique constraint (SOFTWARE.SYS_C0014995) violated

字段加引号

在 SQL 语句中,字段最好都加上引号,不然可能会报错:

1
Error : ORA-00900: invalid SQL statement

或:

1
ORA-24344: Success with Compilation Error

SQUENCE

  • 第一次 NEXTVAL 返回的是初始值;随后的 NEXTVAL 会自动增加 INCREMENT BY 对应的值,然后返回增加后的值。
  • CURRVAL 总是返回当前 SEQUENCE 的值,但是在第一次 NEXTVAL 初始化之后才能使用 CURRVAL ,否则会出错。
  • 一次 NEXTVAL 会增加一次 SEQUENCE 的值,所以如果在同一个语句里面使用多个NEXTVAL,其值就是不一样的。
  • 如果指定 CACHE 值,Oracle 就可以预先在内存里面放置一些 SEQUENCE,这样存取的快些。 CACHE 里面的取完后,Oracle 自动再取一组到 CACHE。
  • 但使用 CACHE 或许会跳号,比如数据库突然不正常关闭(shutdown abort), CACHE 中的 SEQUENCE 就会丢失。所以可以在 CREATE SEQUENCE 的时候用 NOCACHE 防止这种情况。

性能

在数据库操作中,触发器的使用耗费系统资源相对较大。如果对于表容量相对较小的表格我们可以忽略触发器带来的性能影响。

考虑到大表操作的性能问题,需要尽可能的减少触发器的使用。对于以上操作,就可以抛弃触发器的使用,直接手动调用序列函数即可,但这样可能在程序维护上稍微带来一些不便。

三、实现自增ID,实现步骤顺序总结

  1. 创建ID为主键的表(PRIMARY KEY)
  2. 创建序列
  3. 创建触发器
  4. 每个表都需要按顺序123建一次,工程量浩大

四、在 Oracle 12c 中设置自增字段

在 Oracle 12c 中设置自增字段就简单多了,因为 ORacle 12c 提供了 IDENTITY 属性:

1
2
3
4
CREATE TABLE "TEST" (
ID NUMBER(11) GENERATED BY DEFAULT ON NULL AS IDENTITY,
NAME VARCHAR2(50BYTE) NOT NULL
);

这样就搞定了!和 MySQL 一样简单!🤣🤣🤣

五、总结

所以如上所属,在 Oracle 中设置自增字段,需要根据不同的版本使用不同的方法:

在 Oracle 11g 中,需要先创建序列(SQUENCE)再创建一个触发器(TRIGGER)。
在 Oracle 12c 中,只需要使用 IDENTITY 属性就可以了。

参考文档

oracle 实现 自增主键功能

在 Oracle 中设置自增列

]]>
<p>如果你经常使用 MySQL,你肯定对 AUTO_INCREMENT 非常熟悉,因为经常要用到它。</p> <h1 id="一、什么是自增列?"><a href="#一、什么是自增列?" class="headerlink" title="一、什么是自增列?"></a>一、什
Oracle 实现与mysql中find_in_set函数的兼容 https://lookphp.github.io/2018/12/06/Oracle-实现与mysql中find-in-set函数的兼容/ 2018-12-06T15:38:49.000Z 2018-12-06T15:41:57.093Z <![CDATA[

find_in_set(str,strList),寻找str在strList中的位置。

sql代码:

1
2
-- 返回结果为1,
SELECT FIND_IN_SET('1','1,2,3') FROM DUAL;

sql代码:

1
2
-- 返回结果为2
SELECT FIND_IN_SET('1','2,1,3') FROM DUAL;

具体创建函数如下:

sql代码:

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
create or replace FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')
RETURN NUMBER IS
l_idx number:=0; -- 用于计算piv_str2中分隔符的位置
str varchar2(500); -- 根据分隔符截取的子字符串
piv_str varchar2(500) := piv_str2; -- 将piv_str2赋值给piv_str
res number:=0; -- 返回结果
res_place number:=0;-- 原字符串在目标字符串中的位置
BEGIN
-- 如果字段是null 则返回0
IF piv_str2 IS NULL THEN
RETURN res;
END IF;
-- 如果piv_str中没有分割符,直接判断piv_str1和piv_str是否相等,相等 res_place=1
IF instr(piv_str, p_sep, 1) = 0 THEN
IF piv_str = piv_str1 THEN
res_place:=1;
res:= res_place;
END IF;
ELSE
-- 循环按分隔符截取piv_str
LOOP
l_idx := instr(piv_str,p_sep);
--
res_place := res_place + 1;
-- 当piv_str中还有分隔符时
IF l_idx > 0 THEN
-- 截取第一个分隔符前的字段str
str:= substr(piv_str,1,l_idx-1);
-- 判断 str 和piv_str1 是否相等,相等则结束循环判断
IF str = piv_str1 THEN
res:= res_place;
EXIT;
END IF;
piv_str := substr(piv_str,l_idx+length(p_sep));
ELSE
-- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=res_path
IF piv_str = piv_str1 THEN
res:= res_place;
END IF;
-- 无论最后是否相等,都跳出循环
EXIT;
END IF;
END LOOP;
-- 结束循环
END IF;
-- 返回res
RETURN res;
END FIND_IN_SET;

对于某些查询mysql只需写出表达式就可以了,但是我写的oracle的需要写出表达式出来
例如:
sql代码:

1
select * from tableA a left join tableB b on FIND_IN_SET(a.id ,b.aid) ;   -- mysql这样写就可以了

sql代码:

1
select * from tableA a left join tableB b on FIND_IN_SET(a.id ,b.aid) >0; -- oracle就要写出具体的表达式

参考文档:
Oracle 实现与mysql中find_in_set函数的兼容

成功创建后的SQL语句,用作记录

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
CREATE OR REPLACE FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')
RETURN NUMBER IS
l_idx number:=0; -- 用于计算piv_str2中分隔符的位置
str varchar2(500); -- 根据分隔符截取的子字符串
piv_str varchar2(500) := piv_str2; -- 将piv_str2赋值给piv_str
res number:=0; -- 返回结果
res_place number:=0;-- 原字符串在目标字符串中的位置
BEGIN
-- 如果字段是null 则返回0
IF piv_str2 IS NULL THEN
RETURN res;
END IF;
-- 如果piv_str中没有分割符,直接判断piv_str1和piv_str是否相等,相等 res_place=1
IF instr(piv_str, p_sep, 1) = 0 THEN
IF piv_str = piv_str1 THEN
res_place:=1;
res:= res_place;
END IF;
ELSE
-- 循环按分隔符截取piv_str
LOOP
l_idx := instr(piv_str,p_sep);
--
res_place := res_place + 1;
-- 当piv_str中还有分隔符时
IF l_idx > 0 THEN
-- 截取第一个分隔符前的字段str
str:= substr(piv_str,1,l_idx-1);
-- 判断 str 和piv_str1 是否相等,相等则结束循环判断
IF str = piv_str1 THEN
res:= res_place;
EXIT;
END IF;
piv_str := substr(piv_str,l_idx+length(p_sep));
ELSE
-- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=res_path
IF piv_str = piv_str1 THEN
res:= res_place;
END IF;
-- 无论最后是否相等,都跳出循环
EXIT;
END IF;
END LOOP;
-- 结束循环
END IF;
-- 返回res
RETURN res;
END FIND_IN_SET;

]]>
<p>find_in_set(str,strList),寻找str在strList中的位置。</p> <p>sql代码:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span cla
php安装oci8扩展 https://lookphp.github.io/2018/12/06/php安装oci8扩展/ 2018-12-06T15:38:26.000Z 2018-12-11T15:39:16.650Z <![CDATA[

适用环境

  • 操作系统:Windows10 64位
  • PHPstudy集成环境

安装过程

安装一,配置文件开启扩展文件

在phpstudy集成工具中打开PHP的配置文件php.ini 。找到 ";extension=php_oci8.dll"这句话,将其前面的分号去掉,结果如下:

1
2
3
extension=php_oci8.dll      ; Use with Oracle 10gR2 Instant Client
extension=php_oci8_11g.dll ; Use with Oracle 11gR2 Instant Client
extension=php_pdo_oci.dll

题外话,一般我们开启扩展支持,只需要在php.ini中打开扩展就可以。
比如要连接oracle数据库,我们就只要打开 php_oci8.dll 和 php_oci8_11g.dll 就可以了。但是我们打开后,查看phpinfo()并没有开启,也没错误提示,这个问题就有点大,经过一番百度后,发现还需要安装客户端,所以这里我们还需要下载oracle的客户端,直接下载只有客户端支持库的。

安装二:下载并安装客户端

下载地址:
32位链接 密码: cp3v
64位链接 密码: wdst

注意:
这里的32位,64位不是指的Windows操作系统,而是要根据你安装的PHP的位数,就好比今天我纠结了好久的为什么不行,然后注意到安装的是64位的客户端,按照系统看的。而PHP却是32位的(我是用的是集成环境 phpStudy),后更换成32位的客户端安装就真的可以了。附:如何判断PHP是32位,还是64位?

配置系统变量

将路径D:\Program Files (x86)\Oracle\Instant Client\bin添加到系统变量中。

配置环境变量.png
配置环境变量.png

根据Oracle服务器的配置,修改Instant Client的配置

Oracle服务器的配置地址:D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora

tnsnames.ora文件内容如下:

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
# tnsnames.ora Network Configuration File: D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.

LISTENER_ORCL =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))


ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)

ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl.16.22.64)
)
)

参照服务器的配置,修改Instant Client的配置:
Instant Client的地址:D:\Program Files (x86)\Oracle\Instant Client\network\admin\tnsnames.ora
tnsnames.ora文件内容:

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
# tnsnames.ora Network Configuration File.
# Generated by Oracle configuration tools.

# Sample:
#DatabaseName =
# (DESCRIPTION =
# (ADDRESS_LIST =
# (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
# )
# (CONNECT_DATA =
# (SERVER = DEDICATED)
# (SERVICE_NAME = ServiceName)
# (INSTANCE_NAME = InstanceName)
# )
# )

# Modify the following content to fit your own needs.
ORCL=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCL
)
)

至此,打开phpinfo页面,查看oci8的相关扩展信息是否开启,如图。

php的oci8扩展信息.png
php的oci8扩展信息.png

使用如下代码链接Oracle时报错,报错信息如下

链接代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// Create connection to Oracle
$conn = oci_connect("数据库名称", "数据库密码", "//localhost/orcl");
if (!$conn) {
$m = oci_error();
echo $m['message'], "\n";
exit;
}
else {
print "Connected to Oracle!";
}
// // Close the Oracle connection
oci_close($conn);

错误码:

Oracle 报错ORA-12514: TNS:listener does not currently know of service requested in connec

通过上网查到可通过修改listener.ora文件解决第5步的错误

添加了一段在安装目录D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN 下文件修改了加上一段复制的代码(灰色选中部分):

12514错误配置文件.png
12514错误配置文件.png

1
2
3
4
5
6
7
8
9
10
11
12
13
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\app\Administrator\product\11.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\product\11.2.0\dbhome_1\bin\oraclr11.dll")
)(SID_DESC =
(GLOBAL_DBNAME = ORCL)
(ORACLE_HOME = D:\app\Administrator\product\11.2.0\dbhome_1)
(SID_NAME = ORCL)
)
)

关掉Service和LISTENER,再启动Service和LISTENER

注意: 复制请留意到ORACLE_HOME =目录,复制目录一定是要本机文件目录,细节真的很重要!

参考文档:
在 Linux 和 Windows 上安装 PHP 和 Oracle Instant Client
PHP 无法开启 OCI8 扩展原因
Windows PHP/phpStudy 连接 甲骨文Oracle 数据库 oci8
Oracle 报错ORA-12514: TNS:listener does not currently know of service requested in connec

]]>
<h1 id="适用环境"><a href="#适用环境" class="headerlink" title="适用环境"></a>适用环境</h1><ul> <li>操作系统:Windows10 64位</li> <li>PHPstudy集成环境</li> </ul> <h1
阿里云https+nginx服务搭建及配置 https://lookphp.github.io/2018/12/06/阿里云https-nginx服务搭建及配置/ 2018-12-06T15:08:44.000Z 2018-12-06T15:28:12.553Z <![CDATA[

本文不会介绍https相关知识,只是把我创建https服务的过程分享出来,供读者参考。并且已经假设你已经购买了服务器和域名。

购买证书

  • 通过控制台进入CA证书服务,点击右上角的购买证书,进入如下图的界面,选择免费1年的SymantecDV SSL

    image
    image
  • 点击购买,一路点过去,然后回到证书服务主页,会出现一条订单信息,点击补全,如下图所示。

image
image

-然后按照要求,首先填写你要申请证书的完整域名(例如www.test.com,因为此证书为单域名,不能使用通配符);

  • 然后填写个人信息,值得注意的是需要勾选下图红圈包围的选项,让验证自动化进行,不用手动操作;然后下一步,完成信息补全,等待几分钟,验证就可以通过。

image

添加443端口(https)安全组规则

  • 为了安全,阿里云只开放了少部分的端口,像常见的80、443端口,都需要我们手动开启。在等待证书验证期间,你可以去检查一下你的服务器的安全组配置,看一下是否加入了443端口的链接,防止后面连接不上。创建的新规则如下图。
image
image

下载证书

  • 几分钟后,可以看到下图的状态。

    image
    image
  • 选择为nginx制作的证书,并下载到本地。

image
image

配置nginx服务器

  • 把这个文件解压后,会有两个文件,分别为****.pem****.key(可以修改成你需要的名字),将这两个文件拷贝到你的Nginx根目录下的cert文件夹内(自己创建的,也可以命名成其他名字)。

  • 接下来就要配置Nginx服务器了。

  • 如果你配置了反向代理,就去conf.d目录下,修改你要配置https的conf文件。下面贴一个范例配置。

  • 其中端口80为http链接,设置为重定向https;端口443为https链接。
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
upstream blog {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name www.test.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.test.com;
index index.html;
ssl_certificate /etc/nginx/cert/***.pem;
ssl_certificate_key /etc/nginx/cert/***.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
expires off;
sendfile off;
proxy_pass http://test;
}
}

修改防火墙规则

  • 打开配置文件 $ vim /etc/sysconfig/iptables 增加443端口
    -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
  • 重启iptables
    service iptables restart

测试

  • 配置完以后运行nginx -t查看配置文件是否有误。
    • 如果通过了运行 nginx -s reload重新加载配置,去浏览器输入链接,此时成功进入https链接✌️。

配置过程中遇到的问题及解决办法

  • 如何验证是否开启443端口?
    telent www.你的域名.com 443

  • Nginx 配置 Https 出现no “ssl_certificate” is defined in server listening on SSL port while SSL handshaking怎么处理?

Solution:
you should need to add following to nginx server block
listen 443 default_server ssl;
example:-
server {
listen 443 ssl;
ssl_certificate /etc/nginx/cert/.pem;
ssl_certificate_key /etc/nginx/cert/
.key;
}

如上面所说,将server中的ssl声明复制一份到nginx.conf中的http模块中,或conf.d/default.conf中。http中声明的全局SSL证书只是个打酱油的,只是为了不让nginx报上述no “ssl_certificate” is defined的错误,真正生效的证书配置还是在server段。

参考文档:

]]>
<blockquote> <p>本文不会介绍https相关知识,只是把我创建https服务的过程分享出来,供读者参考。并且已经假设你已经购买了服务器和域名。</p> </blockquote> <h1 id="购买证书"><a href="#购买证书" class="header
Vultr VPS搭建SS教程 https://lookphp.github.io/2018/04/12/Vultr-VPS搭建SS教程/ 2018-04-12T14:46:09.000Z 2018-04-12T14:53:47.821Z <![CDATA[

Vultr VPS搭建SS教程

本系列文章自由转载,注明原文地址即可。

国外服务器的购买

这里我选择的是Vultr,对比了很多国外的服务器,这个蛮靠谱的,且搭建成功后看youtube1080p完全无压力。

这里是链接:Vultr The Infrastructure Cloud™

当然,已经有服务器的小伙伴,直接从==快速搭建ShadowSocks==开始看

Vultr服务器价格

Vultr服务器按小时计费,最低0.004美元/h,算起来2.5美元/月,且destory掉服务器是不收费的,所以不用担心如果暂时没有使用还一直扣费的问题,如下图所示:

image
image

最低价格的服务器是512M的内存,500G的带宽,只能说99%的情况下完全够用了!

注册Vultr

首先打开Vultr链接,点击Create Account

充值Vultr

image
image

注册完成之后就是充值,Vultr提供4种充值方式,如下图:

image
image

这里我选择支付宝,因为方便快捷,但是最低消费10美元,也不多,60多人民币,如下图:

image
image

付款之后,就可以看到账户的钱多了

选择VPS的位置

首先,位置很重要!我们如何选择呢,当然有科学的办法,ping它!

Vultr的服务器有很多位置,下面我测试的东京节点和新加坡节点的数据如下:

image
image
image
image

这么看来还是东京的节点速度比较好,当然这个因人而异,在中国不同的地理位置访问国外不同位置的服务器速度也不一样。(下面提供了下载地址,下载下来双击运行即可)。

测速脚本下载地址:
点我下载 测速.bat

脚本内容如下:

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

@echo off
echo ===========================================
echo 东京
ping hnd-jp-ping.vultr.com

echo ============================================
echo 新加坡
ping sgp-ping.vultr.com

echo ===========================================
echo (AU) Sydney, Australia[悉尼]
ping syd-au-ping.vultr.com

echo ===========================================
echo 德国 法兰克福
ping fra-de-ping.vultr.com

echo ===========================================
echo 荷兰 阿姆斯特丹
ping ams-nl-ping.vultr.com

echo ===========================================
echo 英国 伦敦
ping lon-gb-ping.vultr.com

echo ===========================================
echo 法国 巴黎
ping par-fr-ping.vultr.com

echo ===========================================
echo 美东 华盛顿州 西雅图
ping wa-us-ping.vultr.com

echo ===========================================
echo 美西 加州 硅谷
ping sjo-ca-us-ping.vultr.com

echo ===========================================
echo 美西 加州 洛杉矶
ping lax-ca-us-ping.vultr.com

echo ===========================================
echo 美东 芝加哥
Chicago, Illinois[美东 芝加哥]
ping il-us-ping.vultr.com

echo ===========================================
echo 美中 德克萨斯州 达拉斯
ping tx-us-ping.vultr.com

echo ===========================================
echo 美东 新泽西
ping nj-us-ping.vultr.com

echo ===========================================
echo 美东 乔治亚州 亚特兰大
ping ga-us-ping.vultr.com

echo ===========================================
echo 美东 佛罗里达州 迈阿密
ping fl-us-ping.vultr.com
pause

根据测速的结果,我选择东京位置的VPS

创建VPS

左侧菜单栏Servers,点击+,如下图:

image
image

选择VPS的位置,如下图:

image
image

选择操作系统和价格,如下图:

image
image

点击最下面的Deploy Now,如下图:

image
image

创建成功

image
image

VPS的信息

安装成功之后,点击Manage

image
image

可以看到你购买的VPS的信息,如下图所示:

image
image

ping一下ip地址,100ms多一点,这个速度相当可以了,如下图:

image
image

VPS的使用

下载Shell

当然是选择先连接它了,我们选择的工具是XShell

下载地址:Xshell下载

下载完成之后安装,下一步即可

image
image

接着选择免费为家庭/学校

image
image

语言选择中文:

image
image

安装成功后打开

连接VPS

打开Xshell,选择文件->新建,输入VPS的IP,IP地址就在Vultr的管理页面上,如下图所示:

image
image

点击确定,输入用户名,默认应该为root,如下图:

image
image

接着输入密码:

image
image

连接成功:

image
image

快速搭建ShadowSocks(二选一)

一键安装

使用方法

在Xshell中依次运行以下命令

1
2
3
4
5
wget --no-check-certificate -O shadowsocks.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh

chmod +x shadowsocks.sh

./shadowsocks.sh 2>&1 | tee shadowsocks.log

接着按照提醒输入你的密码,端口和加密方式,如下图:

image
image
image
image

然后可以去听首歌~,成功安装之后有你配置的信息显示,记住这些信息,然后跳过下面的手动安装部分,直接去看客户端连接部分即可,如下图:

image
image

以上脚本来源于秋水逸冰

手动安装

安装依赖包

在XShell的控制台输入:

1
2
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py

一个个的来,如下图:

image
image
安装ShadowSocks
1
2
pip install --upgrade pip
pip install shadowsocks

如下图:

image
image
创建ShadowSocks配置文件
单端口
1
vi /etc/shadowsocks.json

输入以下内容,然后点ESC后输入:wq保存退出

1
2
3
4
5
6
{
"server": "0.0.0.0",
"server_port": 2018,
"password": "12345678",
"method": "aes-256-cfb"
}
多端口

(可选,配置了单端口就不要配置这个)多端口的配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
{
"server": "0.0.0.0",
"port_password": {
"8381": "password1",
"8382": "password2",
"8383": "password3",
"8384": "password4"
},
"timeout": 300,
"method": "aes-256-cfb"
}

我采取的是单端口配置,如下图所示:

image
image
image
image
配置防火墙
1
systemctl stop firewalld.service
image
image
启动ShadowSocks服务
1
ssserver -c /etc/shadowsocks.json -d start

如图所示:

image
image

下面的是关闭,启动成功之后不要执行

关闭ShadowSocks服务
1
ssserver -c /etc/shadowsocks.json -d stop

连接ShadowSocks,体会科学上网的魅力

Windows客户端

下载地址:
Shadowsocks-4.0.7.zip

下载完成之后解压打开,如下图所示:

image
image

按照你自己的配置完成之后,点击确定,然后在托盘中右键这个小飞机,启动系统代理
,灰色的小飞机就会亮起来,如下图:

image
image

然后就可以畅游网络了~

测试地址:

安卓连接

下载地址:shadowsocks.apk

配置和windows差不多,配置完成后点击右上角的开启按钮即可,如下图:

image
image

IOS连接

参考链接:http://www.360doc.com/content/17/0614/06/37032448_662846097.shtml

MAC 连接

下载地址:
ShadowsocksX-2.6.3.dmg

测试结果

4K Youtube完成无压力

image
image

写在后面的话

搭建完成后推荐看这篇文章,完成对网速的优化:VPS搭建BBR加速教程(youtube1440p无压力)

如果想多利用Vultr,搭建个人博客,看这篇文章:10分钟搭建Java开源博客Tale-超详细

]]>
<h1 id="Vultr-VPS搭建SS教程"><a href="#Vultr-VPS搭建SS教程" class="headerlink" title="Vultr VPS搭建SS教程"></a>Vultr VPS搭建SS教程</h1><blockquote> <p>本系列文章
ElasticSearch CURD https://lookphp.github.io/2018/03/30/ElasticSearch-CURD/ 2018-03-29T16:21:50.000Z 2018-03-29T16:29:15.815Z <![CDATA[

开始使用

接下来,我们看看如何建立索引、创建文档等,就好比在 MySQL 中进行诸如创建数据库,插入数据等操作。

Index:创建与更新索引

在ElasticSearch中,Index这一动作类比于CRUD中的Create与Update,当我们尝试为某个不存在的文档建立索引时,会自动根据其类似于ID创建新的文档,否则就会对原有的文档进行修改。

ElasticSearch使用PUT请求来进行Index操作,你需要提供索引名称、类型名称以及可选的ID,格式规范为:http://localhost:9200///[]。其中索引名称可以是任意字符,如果ElasticSearch中并不存在该索引则会自动创建。

添加文档

下面,我们将创建一个存储电影信息的Document :

  • Index 的名称为movie
  • Type 的名称为adventure
  • Document 有两个字段: name和actors

我们使用 Elasticsearch 提供的 RESTful API 来执行上述操作,如图所示:

image.png
image.png
  • url表示一个资源,比如 /movie/adventure/1 就表示一个indexmovietypeadventureid1document
  • http 方法操作资源,如使用 GET 获取资源,使用 POST、PUT新增或更新资源,使用 DELETE 删除资源等

向指定的/Index/Type 发送 PUT 请求,就可以在Index 里面新增一条记录。比如,向/movie/adventure发送请求,就可以新增电影记录。

我们可以使用 curl 命令来执行上述操作:

1
2
3
4
5
curl -XPUT "http://localhost:9200/movie/adventure/1" -d '
{
"name": "Life of Pi",
"actors": ["Suraj" , "Irrfan"]
}'

如果可以,推荐使用httpie,类似 curl,但比 curl 更好用,将上面的命令换成 httpie,如下:

1
http put :9200/movie/adventure/1 name="Life of Pi" actors:='["Suraj", "Irrfan"]'

服务器返回的 JSON 对象,会给出Index、Type、Id、Version 等信息。
成功返回的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "movie",
"_type": "adventure",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}

可以看到,我们已经成功创建了一个 _indexmovie_typeadventure_id 为 1 的文档,最后的1是该条记录的 Id。它不一定是数字,任意字符串(比如abc)都可以。

ElasticSearch对于PUT请求的响应中包含了是否操作成功、文档编号等信息。

查询GET

我们通过 GET 请求来查看这个文档的信息:

1
curl -XGET localhost:9200/movie/adventure/1

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_index": "movie",
"_type": "adventure",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"name": "Life of Pi",
"actors": [
"Suraj",
"Irrfan"
]
}
}

可以看到,原始的文档数据存在了 _source 字段中。

新增记录的时候,也可以不指定 Id,这时要改成 “POST” 请求。

1
2
3
4
curl -X POST 'localhost:9200/movie/adventure' -d '
{
"name": "Life of Pi"
}'

更新整个文档

更新记录就是使用 PUT 请求,重新发送一次数据。不过我们这次务必要加上需要修改的文档的ID编号,否则就变成添加了。接下来我们尝试对刚才新建立的文档进行些修改,添加某些关键字属性。

当我们使用 PUT 方法指明文档的 _index, _type_id时,如果 _id 已存在,则新文档会替换旧文档,此时文档的 _version 会增加 1,并且 _created 字段为 false。比如:

1
2
3
4
curl -XPUT "http://localhost:9200/movie/adventure/1" -d'
{
"name": "Life of Pi"
}'

返回的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index": "movie",
"_type": "adventure",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false
}

添加和修改的比较

对于此操作的ElasticSearch的响应与前者很类似,不过可以看出_version属性值已经发生了变化:

变化的字段添加修改
_version12
resultcreatedupdated
createdtruefalse

GET
最简单的获取某个文档的方式即是基于文档ID进行搜索

1
curl -XGET 'http://localhost:9200/movie/adventure/1?pretty=true'

返回的结果:

1
2
3
4
5
6
7
8
9
10
{
"_index" : "movie",
"_type" : "adventure",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "Life of Pi"
}
}

可以看到,actors 这个字段已经不存在了,文档的 _version 变成了 2。

如何避免原文档被替换?

因此,为了避免在误操作的情况下,原文档被替换,我们可以使用_create 这个 API,表示只在文档不存在的情况下才创建新文档(返回 201 Created),如果文档存在则不做任何操作(返回 409 Conflict),命令如下:

1
2
3
4
curl -XPUT "http://localhost:9200/movie/adventure/1/_create" -d'
{
"name": "Life of Pi"
}'

由于文档 id 存在,会返回 409 Conflict。结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[adventure][1]: version conflict, document already exists (current version [2])",
"index_uuid": "Kn_OWg1TT5GLaMInWlREHQ",
"shard": "3",
"index": "movie"
}
],
"type": "version_conflict_engine_exception",
"reason": "[adventure][1]: version conflict, document already exists (current version [2])",
"index_uuid": "Kn_OWg1TT5GLaMInWlREHQ",
"shard": "3",
"index": "movie"
},
"status": 409
}

局部更新

在有些情况下,我们只想更新文档的局部,而不是整个文档,这时我们可以使用 _update 这个 API。

现在,待更新的文档信息如下:

1
2
3
4
5
6
7
8
9
10
{
"_index" : "movie",
"_type" : "adventure",
"_id" : "1",
"_version" : 2,
"found" : true,
"_source" : {
"name" : "Life of Pi"
}
}

最简单的 update 请求接受一个局部文档参数 doc,它会合并到现有文档中,请求方式需要变更为POST方式:将对象合并在一起,存在的标量字段被覆盖,新字段被添加。

1
2
3
4
5
6
7
curl -XPOST "http://localhost:9200/movie/adventure/1/_update" -d'
{
"doc": {
"name": "life of pi",
"actor": ["jack"]
}
}'

上面的命令中,我们添加了一个新的字段:actors,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"_index" : "movie",
"_type" : "adventure",
"_id" : "1",
"_version" : 8,
"found" : true,
"_source" : {
"name" : "life of pi",
"actor" : [
"jack"
]
}
}

Delete:删除索引

现在我们尝试去删除上文中插入的部分文档,对于要删除的文档同样需要传入索引名、类型名与文档名这些信息,譬如:

1
curl -XDELETE "http://localhost:9200/movie/adventure/1"

返回的结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"found": true,
"_index": "movie",
"_type": "adventure",
"_id": "1",
"_version": 3,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}
}

在我们删除了该文档之后,再次尝试用GET方法获取该文档信息时,会得到如下的响应:

1
2
3
4
5
6
{
"_index" : "movie",
"_type" : "adventure",
"_id" : "1",
"found" : false
}

查看当前节点的所有 Index

1
http://localhost:9200/_cat/indices?v

返回的结果:

1
2
3
4
5
health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open my_index aBM6KLOLSJ6TWtp87sC5qA 5 1 1 0 4.1kb 4.1kb
yellow open accounts 2i3MNbwCSeSxZCBDikaMzA 5 1 2 0 7.9kb 7.9kb
yellow open movies -uB5sD6QTt6vmD4YPpJFaQ 5 1 1 0 5.1kb 5.1kb
yellow open liuxingwang 6KRPO9fJRVmWC7X3G69HQQ 5 1 0 0 955b 955b

小结

  • Elasticsearch 通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单
  • 在创建文档时,我们可以用 POST 方法指定将文档添加到某个 _index/_type下,来让 Elasticsearch自动生成唯一的 _id
  • 而用 PUT 方法指定将文档的 _index/_type/_id
  • 我们看不到HTTP头是因为我们没有让curl显示它们,如果要显示,使用curl命令后跟-i参数:
]]>
<h1 id="开始使用"><a href="#开始使用" class="headerlink" title="开始使用"></a>开始使用</h1><p>接下来,我们看看如何建立索引、创建文档等,就好比在 MySQL 中进行诸如创建数据库,插入数据等操作。</p> <p>Ind
ElasticSearch快速入门 https://lookphp.github.io/2018/03/22/ElasticSearch快速入门/ 2018-03-22T15:33:11.000Z 2018-03-22T15:40:45.776Z <![CDATA[

在安装 Elasticsearch 之前,请确保你的计算机已经安装了 Java。目前 Elasticsearch 的最新版是 5.2,需要安装 Java 8,如果你用的是老版本的 Elasticsearch,如 2.x 版,可用 Java 7,但还是推荐使用 Java 8。

安装前检查

可以使用如下的命令检查 Java 的版本

1
$ java -version

接着,我们可以从这里下载最新版本的 Elasticsearch,也可使用 wget 下载,如下:

1
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.tar.gz

下载完后进行解压

1
$ tar -zxvf elasticsearch-5.5.1.tar.gz

运行

注意:启动elasticsearch的用户不能是root。

首先,我们进入到刚刚解压出来的目录中:

1
$ cd elasticsearch-5.5.1

接着,使用如下命令启动 Elasticsearch:

1
$ ./bin/elasticsearch

此时,如果正常的话,你可以在终端看到类似如下的输出:

1
2
3
4
5
6
7
[2017-03-04T23:25:09,961][INFO ][o.e.n.Node               ] [] initializing ...
[2017-03-04T23:25:10,073][INFO ][o.e.e.NodeEnvironment ] [yO11WLM] using [1] data paths, mounts [[/ (/dev/disk0s2)]], net usable_space [141.1gb], net total_space [232.9gb], spins? [unknown], types [hfs]
[2017-03-04T23:25:10,074][INFO ][o.e.e.NodeEnvironment ] [yO11WLM] heap size [1.9gb], compressed ordinary object pointers [true]
[2017-03-04T23:25:10,095][INFO ][o.e.n.Node ] node name [yO11WLM] derived from node ID [yO11WLMOQDuAOpZbYZYjzw]; set [node.name] to override
[2017-03-04T23:25:10,100][INFO ][o.e.n.Node ] version[5.5.1], pid[7607], build[db0d481/2017-02-09T22:05:32.386Z], OS[Mac OS X/10.11.5/x86_64], JVM[Oracle Corporation/Java HotSpot(TM) 64-Bit Server VM/1.8.0_102/25.102-b14]
[2017-03-04T23:25:11,363][INFO ][o.e.p.PluginsService ] [yO11WLM] loaded module [aggs-matrix-stats]
...

上面的命令是在前台运行的,如果想在后台以守护进程模式运行,可以加 -d 参数。

Elasticsearch 启动后,也启动了两个端口 9200 和 9300:

  • 9200 端口:HTTP RESTful 接口的通讯端口
  • 9300 端口:TCP 通讯端口,用于集群间节点通信和与 Java 客户端通信的端口

默认运行端口

安装成功后,Elastic 就会在默认的9200端口运行。

请求地址

现在,让我们做一些测试。在浏览器访问链接http://localhost:9200/,或使用 curl 命令:

1
curl 'http://localhost:9200/?pretty'

我们可以看到类似如下的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "MxO5-r8",
"cluster_name": "elasticsearch",
"cluster_uuid": "uQakSfM7Qi-cphDkxwRdxg",
"version": {
"number": "5.5.1",
"build_hash": "19c13d0",
"build_date": "2017-07-18T20:44:24.823Z",
"build_snapshot": false,
"lucene_version": "6.6.0"
},
"tagline": "You Know, for Search"
}

相关概念

在进一步使用 Elasticsearch 之前,让我们先了解几个关键概念。

在逻辑层面

  • Index (索引):这里的 Index 是名词,一个 Index 就像是传统关系数据库的 - Database,它是 Elasticsearch 用来存储数据的逻辑区域。我们唯一需要做的仅仅是选择一个索引名。这个名字必须是全部小写,不能以下划线开头,不能包含逗号。
  • Type (类型):文档归属于一种 Type,就像是关系数据库中的一个 Table
  • Document (文档):Elasticsearch 使用 JSON 文档来表示一个对象,就像是关系数据库中一个 Table 中的一行数据
  • Field (字段):每个文档包含多个字段,类似关系数据库中一个 Table 的列

在物理层面

  • Node (节点):node 是一个运行着的 Elasticsearch 实例,一个 node 就是一个单独的 server
  • Cluster (集群):cluster 是多个 node 的集合
  • Shard (分片):数据分片,一个 index 可能会存在于多个 shard

Relational DB 和 Elasticsearch的区别

在ElasticSearch中,我们常常会听到Index、Type以及Document等概念,那么它们与传统的熟知的关系型数据库中名称的类比如下:

MysqlElasticsearch
Database(数据库)Index(索引)
Table(表)Type(类型)
Row(行)Document(文档)
Column(列)Field(字段)
Schema(表设计)Mapping(映射)
Index(索引)Everything Indexed by default(所有字段都被索引)
SQL(结构化查询语言)Query DSL(查询专用语言)

其文件目录结构如下

1
2
3
4
5
6
7
8
9
10
elasticsearch---这是Elasticsearch解压的目录
  bin---这里面是ES启动的脚本

  conf---elasticsearch.yml为ES的配置文件

  data---这里是ES得当前节点的分片的数据,可以直接拷贝到其他的节点进行使用

  logs---日志文件

  plugins---这里存放一些常用的插件,如果有一切额外的插件,可以放在这里使用。

HTTP请求链接说明

一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

curl -X://:/?<QUERY_STRING>’ -d ‘‘

< > 标记的部件

参数说明
VERB适当的 HTTP _方法_ 或 _谓词_ : GETPOSTPUTHEAD 或者 DELETE
PROTOCOLhttp 或者 https(如果你在 Elasticsearch 前面有一个 https 代理)
HOSTElasticsearch 集群中任意节点的主机名,或者用 +localhost+ 代表本地机器上的节点。
PORT运行 Elasticsearch HTTP 服务的端口号,默认是 9200
PATHAPI 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats_nodes/stats/jvm
QUERY_STRING任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
BODY一个 JSON 格式的请求体 (如果请求需要的话)

解决不能以root身份运行

在ElasticSearch 2.x版本中,默认是不允许以Root用户身份运行实例,可以使用bin/elasticsearch -Des.insecure.allow.root=true来以Root身份启动集群,此外还可以使用bin/elasticsearch -f -Des.path.conf=/path/to/config/dir参数来读取相关的.yml或者.json配置。

Restful API

参考文档:
https://juejin.im/entry/57e222528ac24700617b8c78
https://imququ.com/post/elasticsearch.html
http://blog.csdn.net/lvhong84/article/details/23936697

]]>
<p>在安装 Elasticsearch 之前,请确保你的计算机已经安装了 Java。目前 Elasticsearch 的最新版是 5.2,需要安装 Java 8,如果你用的是老版本的 Elasticsearch,如 2.x 版,可用 Java 7,但还是推荐使用 Java 8。
使用hexo搭建博客教程 https://lookphp.github.io/2018/03/22/使用hexo搭建博客教程/ 2018-03-22T15:17:05.000Z 2018-03-22T15:31:14.886Z <![CDATA[

Hexo的安装需要通过npm命令来进行,安装完node.js之后就默认安装了npm包管理工具,而npm的官方仓库位于境外,由于众所周知的原因,我们大陆用户基本是访问不了官方源了,所以推荐大家使用淘宝镜像进行替换。

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

]]>
<p>Hexo的安装需要通过npm命令来进行,安装完node.js之后就默认安装了npm包管理工具,而npm的官方仓库位于境外,由于众所周知的原因,我们大陆用户基本是访问不了官方源了,所以推荐大家使用淘宝镜像进行替换。</p> <h1 id="Quick-Start"><a hr
Hello World https://lookphp.github.io/2018/03/20/hello-world/ 2018-03-20T15:29:38.066Z 2018-03-20T15:29:38.066Z <![CDATA[

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

]]>
<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.