0%

issue
JDK未导入自签名证书,调HTTPS接口会有如下错误

1
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ``` ```java Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ... 19 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ... 25 more

solution

1
2
3
4
5
cd ${JAVA_HOME}/jre/lib/security

keytool -import -alias codz -keystore cacerts -file ${JAVA_HOME}/jre/lib/security/codz.cer

keytool -list -keystore cacerts -alias codz

Reference

  1. OpenSSL安装

    OpenSSL官网,或者参考 linux升级OpenSSL

    中间可能会遇到 openssl.cnf 的问题,请使用 openssl-1.0.1t.tar.gz 包 apps下的 demoCA 和 openssl.cnf

  2. 证书生成

    • 单向认证,参考 Nginx单向认证的安装配置

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      openssl genrsa -des3 -out server.key 2048 #自定义密码

      openssl req -new -key server.key -out server.csr

      #---------------------------------------------------------------------------------------------------------------
      Enter pass phrase for server.key: 自定义密码
      Country Name (2 letter code) [XX]: CN #国家
      State or Province Name (full name) []: GD #区域或是省份
      Locality Name (eg, city) [Default City]: SZ #地区局部名字
      Organization Name (eg, company) [Default Company Ltd]: Test #机构名称:填写公司名
      Organizational Unit Name (eg, section) []: Test #组织单位名称:部门名称
      Common Name (eg, your name or your server's hostname) []: *.domain.com #网站域名
      Email Address []: admin@domain.com #邮箱地址
      A challenge password []: #输入一个密码
      An optional company name []: #一个可选的公司名称
      #---------------------------------------------------------------------------------------------------------------

      怎么让nginx配置SSL安全证书重启免输入密码,不然Nginx、Tomcat使用该私钥启动的时候需要输入上面的密钥

      openssl rsa -in server.key -out server.key.unsecure
      openssl x509 -req -days 365 -in server.csr -signkey server.key.unsecure -out server.crt #使用上面的密钥和CSR对证书进行签名

    • 双向认证,参考 openssl生成SSL证书的流程

      CA根证书的生成

      1
      2
      3
      4
      5
      6
      # Generate CA private key   
      openssl genrsa -out ca.key 2048
      # Generate CSR
      openssl req -new -key ca.key -out ca.csr
      # Generate Self Signed certificate(CA 根证书)
      openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

      用户证书的生成

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      # 服务器端用户证书
      # private key
      openssl genrsa -des3 -out server.key 1024
      # generate csr
      openssl req -new -key server.key -out server.csr
      # generate certificate
      openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

      # 客户端用户证书
      openssl genrsa -des3 -out client.key 1024
      openssl req -new -key client.key -out client.csr
      openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
      免密钥启动同上,TXT_DB error number 2 异常请参考 openssl TXT_DB error number 2

      生成pem格式证书
      有时需要用到pem格式的证书,可以用以下方式合并证书文件(crt)和私钥文件(key)来生成

      1
      2
      $cat client.crt client.key> client.pem
      $cat server.crt server.key > server.pem
  3. Nginx、Tomcat配置HTTPS

    nginx.conf添加

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate /work/openssl/single/server.crt;
    ssl_certificate_key /work/openssl/single/server.key.unsecure;

    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
    allow all;
    proxy_pass https://192.168.1.121:443;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Real-Ip $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    }

    tomcat server.xml添加

    1
    2
    3
    4
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
    maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
    clientAuth="false" SSLCertificateFile="/work/openssl/single/server.crt" SSLProtocol="SSLv2+SSLv3+TLSv1"
    SSLCertificateKeyFile="/work/openssl/single/server.key.unsecure" SSLVerifyClient="optional"/>

    server.xml默认注释了

    1
    2
    3
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
    maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" />

    需要注意protocol中的 Http11AprProtocol 与 Http11NioProtocol,加密算法不支持的话,可能报异常 Java and SSL - java.security.NoSuchAlgorithmException

  4. 一个大坑

    Ubuntu上跑Tengine,代理Windows上的应用,访问HTTPS页面时候总是报504错误,后来又报502错误。

    排查了一个多小时后发现是Windows系统安装了Vmware Workstation,而Vmware的VMware Authorization Service自动启动了。

    还有另外一个Vmware的服务忘记了,这两个服务会影响本地应用使用HTTPS,所以停止掉或禁用掉就可以了。

    HTTP状态码

    502 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

    504 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。   注意:某些代理服务器在DNS查询超时时会返回400或者500错误

参考资料:

检查目前状态

1
2
$ ls -l /lib/systemd/system/default.target
lrwxrwxrwx 1 root root 16 May 12 16:05 /lib/systemd/system/default.target -> graphical.target

设置为默认启动字符界面

1
systemctl set-default multi-user.target

返回默认启动图形界面

1
systemctl set-default graphical.target

其他方法,例如,均失败告终

1
2
3
4
5
6
7
8
9
10
11
#1
sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="text"

sudo update-grub2

#2
sudo vi /etc/init/rc-sysinit.conf

env DEFAULT_RUNLEVEL=3

Reference

背景

ngrok官网被q,而且访问速度慢,最主要的是不支持域名绑定,每次启动都是随机的二级域名,333

ngrok.cc-Sunny-Ngrok内网转发,服务器在香港,访问速度也慢,支持自定义系统域名,但只能定义一个(可以先定义TCP端口转发,保存后编辑,可以修改成系统分配域名,这样子就可以有多个自定义的系统域名,然并卵,客户端连接不上,一直提示该域名已被注册,官方做限制了吧)。

对比了上面两个服务,加上自己的需求:

  • 需要多个自定义的域名;
  • 尽量提升访问速度;决定自己搭建一个ngrok服务。

搭建ngrok服务需要的资源:

  • 一个域名,需要定义泛解析;
  • 一台ECS,需要公网IP

以下操作建议在Ubuntu上尝试,不建议在Windows上尝试(花了一个晚上搞都没搞成功,第二天早上花一个小时在Ubuntu上完美运行)

拉取ngrok源码

1
git clone git@github.com:inconshreveable/ngrok.git /work/ngrok

使用ngrok.com官方服务时,我们使用的是官方的SSL证书。

自建ngrokd服务,如果不想买SSL证书,我们需要生成自己的自签名证书,并编译一个携带该证书的ngrok客户端。

证书生成过程需要一个NGROK_BASE_DOMAIN

以ngrok官方随机生成的地址693c358d.ngrok.com为例,其NGROK_BASE_DOMAIN就是ngrok.com,如果你要提供服务的地址为example.ngrok.xxx.com,那NGROK_BASE_DOMAIN就应该是ngrok.xxx.com

这里以NGROK_BASE_DOMAIN="codz.me"为例,生成证书的命令如下:

1
2
3
4
5
6
cd /work/ngrok
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=codz.me" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=codz.me" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

ngrok目录下新建了如下文件

1
2
3
4
5
6
-rw-r--r-- 1 root root  985 Jul 21 08:52 device.crt
-rw-r--r-- 1 root root 895 Jul 21 08:52 device.csr
-rw-r--r-- 1 root root 1679 Jul 21 08:52 device.key
-rw-r--r-- 1 root root 1675 Jul 21 08:51 rootCA.key
-rw-r--r-- 1 root root 1103 Jul 21 08:52 rootCA.pem
-rw-r--r-- 1 root root 17 Jul 21 08:52 rootCA.srl

ngrok通过bindata将ngrok源码目录下的assets目录打包到可执行文件(ngrokd和ngrok)中去,assets/client/tls和assets/server/tls下分别存放着用于ngrok和ngrokd的默认证书文件。

我们需要将它们替换成我们自己生成的,因此这一步务必放在编译可执行文件之前。

所以,执行下面拷贝命令:

1
2
3
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key

搭建go环境

Golang官网被q,下载安装包特么慢,Golang中国提供下载站点,我使用的是1.6.3版本;

下载并解压到go的默认安装路径/usr/local/go

1
2
3
cd /work/download
wget http://www.golangtc.com/static/go/1.6.3/go1.6.3.linux-amd64.tar.gz
tar -zxvf go1.6.3.linux-amd64.tar.gz -C /usr/local

修改PATH

1
2
3
4
vi /etc/profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
source /etc/profile

正确配置后,go env可以查看得到当前go的环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

编译安装

进入/work/ngrok目录

1
make release-server release-client

正常的话,ngrok/bin目录下应该有ngrokdngrok两个可执行文件,前面一个是服务端的,后面一个是客户端的;

需要Windows下的ngrok.exe可以通过下面命令构建,正常的话ngrok/bin/windows_amd64下会生成的ngrok.exe文件;

1
GOOS=windows GOARCH=amd64 make release-client

编译mac客户端(没实际操作)

1
GOOS=darwin GOARCH=amd64 make release-client

make很可能出现的错误有(来自Windows下的错误信息,Ubuntu下跑一切正常)

1
2
3
4
5
6
7
8
package archive/zip: unrecognized import path "archive/zip" (import path does not begin with hostname)
package bytes: unrecognized import path "bytes" (import path does not begin with hostname)
package encoding/json: unrecognized import path "encoding/json" (import path does not begin with hostname)
package encoding/xml: unrecognized import path "encoding/xml" (import path does not begin with hostname)
package errors: unrecognized import path "errors" (import path does not begin with hostname)
package expvar: unrecognized import path "expvar" (import path does not begin with hostname)
package flag: unrecognized import path "flag" (import path does not begin with hostname)
package fmt: unrecognized import path "fmt" (import path does not begin with hostname)

启动ngrok

服务端启动

1
2
cd /work/ngrok/bin
ngrokd -domain="codz.me" -httpAddr=":8088" -httpsAddr=":8089"

-domain的内容需要与上面生成证书所填的NGROK_BASE_DOMAIN一致;

自定义http、https提供服务的端口,据此你使用的二级域名应该是 http://[自定义].codz.me:8088

其他有用的启动脚本

  • 后台启动,输出日志

    1
    nohup ngrokd -domain="codz.me" -httpAddr=":8088" -httpsAddr=":8089" >/tmp/ngrok.log 2>&1 &
  • 后台启动不输出日志

    1
    nohup ngrokd -domain="codz.me" -httpAddr=":8088" -httpsAddr=":8089" >/dev/null 2>&1 &

客户端启动

拷贝编译好的ngrok客户端可执行文件到需要的机子上,给予执行权限,创建配置文件ngrok.cfg

1
2
3
4
5
6
7
8
server_addr: "codz.me:4443"
trust_host_root_certs: false

tunnels:
www:
subdomain: "test"
proto:
http: 192.168.1.121:8000

其中,server_addr需要跟NGROK_BASE_DOMAIN填写一致,否则服务端会报证书错误;

trust_host_root_certs需要设置为false;

trust_host_root_certs参数指示建立TLS连接到服务器时ngrok信任的根证书在计算机上。默认情况下,ngrok只信任的ngrok.com根证书;

trust_host_root_certs,对于ngrok官方server一般为true,现在官网国内不能用,通常为自编译的,有自己的证书,所以要设为false

启动客户端ngrok,之后就可以使用http://test.codz.me:8088来访问本地192.168.121:8000的资源了

1
./ngrok -config ngrok.cfg start www

配置文件写法,来自ngrok.cc

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
server_addr: "server.ngrok.cc:4443"
auth_token: "" #授权token,在www.ngrok.cc平台注册账号获取
tunnels:
sunny:
subdomain: "sunny" #定义服务器分配域名前缀,跟平台上的要一样
proto:
http: 80 #映射端口,不加ip默认本机
https: 80
web:
subdomain: "web" #定义服务器分配域名前缀
proto:
http: 192.168.1.100:80 #映射端口,可以通过加ip为内网任意一台映射
https: 192.168.1.100:80
web1:
hostname: "www.sunnyos.com"
proto:
http: 80
web2:
hostname: "sunnyos.com"
proto:
http: 80
ssh:
remote_port: 50001 #服务器分配tcp转发端口,如果不填写此项则又服务器分配
proto:
tcp: 22 #映射本地的22端口
ssh1: #将由服务器分配端口
proto:
tcp: 21

至此,all done.

实测,单个用户通过ngrok访问内网速度有所提升;

多个用户同时访问效果不是很明显,可能与ECS带宽有关(→_→ 1Mbps),ngrok使用多个自定义域名目的已达成,这是重点。

参考:

Create

PUT http://192.168.56.101:9200/school/student/1,自动创建school索引,学生类型,最后指定id为1

1
2
3
4
5
6
7
{
"name":"许薇",
"class":"计算机科学与技术1班",
"sc_id":"001",
"from":"广州",
"birth":"1993-1-1"
}

成功添加后返回下面JSON内容

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

Update

POST http://192.168.56.101:9200/school/student/1/_update,发送要更新的字段,例如

1
2
3
{
"script":"ctx._source.from=\"深圳\""
}

更新成功后,_version字段会+1

1
2
3
4
5
6
7
8
9
10
11
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 4,
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
}
}

再次查询,可以看到from字段是更新了的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 4,
"found": true,
"_source": {
"name": "许薇",
"class": "计算机科学与技术1班",
"sc_id": "001",
"from": "深圳",
"birth": "1993-1-1"
}
}

Read

GET http://192.168.56.101:9200/school/student/1,成功查询到则返回下面JSON数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"name": "许薇",
"class": "计算机科学与技术1班",
"sc_id": "001",
"from": "深圳",
"birth": "1993-1-1"
}
}

Delete

DELETE http://192.168.56.101:9200/school/student/2

成功删除后返回下面JSON信息,其中_version也会+1;

文档删除后,ES保留了删除文档的版本信息,所以仍然可以检查该版本号。

默认情况下,版本信息在删除的60秒内可用,可以通过index.gc_deletes修改可用时间。

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

Elasticsearch 简介

ElasticSearch(简称 ES) 是一个基于 Lucene 构建的开源,分布式,RESTful 搜索引擎。

设计用于云计算中,能够达到搜索实时、稳定、可靠和快速,并且安装使用方便。

支持通过 HTTP 请求,使用 JSON 进行数据索引。另外,ES还有非常强大的统计功能 (facets) , 一个例子:现在系统中的需要实时处理的统计功能从 MySQL 转接到 ElasticSearch , 准确性一致, 速度从原来 1900ms -> 50ms。

Apache Lucene只是一个库。

想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

关系数据库与ES

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields

Elasticsearch 安装

  1. 安装JDK
    需要JDK1.7或以上,官方推荐使用最新版JDK

  2. 安装与启动ES
    下载ES

    1
    https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/2.3.3/elasticsearch-2.3.3.tar.gz

    解压到指定目录

    1
    tar -zxvf elasticsearch-2.3.3.tar.gz

    进入bin目录启动ES

    1
    2
    cd elasticsearch-2.3.3/bin
    ./elasticsearch
    start

    至此,可以查看ES集群的信息

    1
    curl -XGET 'http://localhost:9200?pretty'
    info
  3. 关闭ES

    三种方式关闭:

    • 如果节点是连接到控制台,按下Ctrl+C;

    • 通过发送TERM信号杀掉服务器进程(参考Linux上的kill命令和Windows上的任务管理器);

    • 使用REST API

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //关掉整个集群
      curl -XPOST http://localhost:9200/_cluster/nodes/_shutdown

      //关闭单一节点,假如节点标识符是BlrmMvBdSKiCeYGsiHijdg,如何查看见下一条
      curl –XPOST http://localhost:9200/_cluster/nodes/BlrmMvBdSKiCeYGsiHijdg/_shutdown

      //查看节点标识符
      curl -XGET http://localhost:9200/_cluster/nodes/

      //检查集群健康度
      curl -XGET http://localhost:9200/_cluster/health?pretty
      health

Elasticsearch 插件

Marvel

Marvel用来监控 Elasticsearch 集群实时、历史状态的有力用具,便于性能优化以及故障诊断。

监控主要分为六个层面,分别是集群层、节点层、索引层、分片层、事件层、Sense,在开发环境下免费使用。

1
2
3
4
5
6
7
8
./bin/plugin -i elasticsearch/marvel/latest
Kibana

Kibana是一个用于ElasticSearch分析和查询的仪表盘。

tar zxvf kibana-4.5.0-linux-x64.tar.gz
cd ./kibana-4.5.0-linux-x64/bin/
./kibana

可以通过下行命令来查看节点上的插件列表

1
curl http://localhost:9200/_nodes/_local/plugins

Elasticsearch 配置

config/elasticsearch.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
36
37
38
39
40
41
42
43
44
45
46
47
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: ela
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-1
#
# Add custom attributes to the node:
#
# node.rack: r1
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0
#
# Set a custom port for HTTP:
#
# http.port: 9200
#
# For more information, see the documentation at:
# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>


# personal setting,use for http post add new field
script.update: true
script.mapping: true
script.engine.groovy.file.aggs: true
script.engine.groovy.file.mapping: true
script.engine.groovy.file.search: true
script.engine.groovy.file.update: true
script.engine.groovy.file.plugin: true
script.engine.groovy.indexed.aggs: true
script.engine.groovy.indexed.mapping: true
script.engine.groovy.indexed.search: true
script.engine.groovy.indexed.update: true
script.engine.groovy.indexed.plugin: true
script.engine.groovy.inline.aggs: true
script.engine.groovy.inline.mapping: true
script.engine.groovy.inline.search: true
script.engine.groovy.inline.update: true
script.engine.groovy.inline.plugin: true

cluster.name:保存集群的名字,不同的集群用名字来区分,配置成相同集群名字的各个节点形成一个集群。节点启动时据此自动加入对应的集群,如果集群存在的话。

node.name:实例(该节点)的名字,可以不定义此参数,这时,Elasticsearch自动选择一个唯一的名称。注意,此名称是每次启动时选择的,所以在每次重启后名称可能都不一样。在很长的时间区间或者重启过后,需要在API中提及具体实例名称,或者用监控工具查看节点,自定义一个名称还是很有帮助的。

http.port:HTTP API的默认端口号是9200,Elasticsearch很聪明,如果默认端口不可用,引擎将绑定到下一个可用端口。

network.bind_host:默认情况下 Elasticsearch 的 RESTful 服务只有本机才能访问,也就是说无法从主机访问虚拟机中的服务,可以设置为0.0.0.0以方便主机调式虚拟机。

Reference

在线播放

歌词

阿桑 - 一直很安静
空荡的街景
想找个人放感情
作这种决定
是寂寞与我为邻
我们的爱情
像你路过的风景
一直在进行
脚步却从来不会为我而停
给你的爱一直很安静
来交换你偶尔给的关心
明明是三个人的电影
我却始终不能有姓名
你说爱像云
要自在飘浮才美丽
我终于相信
分手的理由有时候很动听
给你的爱一直很安静
来交换你偶尔给的关心
明明是三个人的电影
我却始终不能有姓名
给你的爱一直很安静
我从一开始就下定决心
以为自己要的是曾经
却发现爱一定要有回应
给你的爱一直很安静
来交换你偶尔给的关心
明明是三个人的电影
我却始终不能有姓名
给你的爱一直很安静
除了泪在我的脸上任性
原来缘分是用来说明
你突然不爱我这件事情

与Myeclipse略不同,除了在Tomcat/conf/server.xml的Host节点下指定外

1
<Context path="/upload" docBase="D:\apache\online_submission\upload" />

还需要在IDEA的

Run/Debug Configurations - Tomcat Server - Server -Tomcat Server Settings

勾选

Deploy applications configured in Tomcat instance

idea.png

查了一些源码,发现commandName其实是set get modelAttributeorg.springframework.web.servlet.tags.form.FormTag

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
public class FormTag extends AbstractHtmlElementTag {

//other codes

/** The default attribute name: &quot;command&quot; */
public static final String DEFAULT_COMMAND_NAME = "command";

private String modelAttribute = DEFAULT_COMMAND_NAME;

/**
* Set the name of the form attribute in the model.
* <p>May be a runtime expression.
*/
public void setModelAttribute(String modelAttribute) {
this.modelAttribute = modelAttribute;
}

/**
* Get the name of the form attribute in the model.
*/
protected String getModelAttribute() {
return this.modelAttribute;
}

/**
* Set the name of the form attribute in the model.
* <p>May be a runtime expression.
* @see #setModelAttribute
*/
public void setCommandName(String commandName) {
this.modelAttribute = commandName;
}

/**
* Get the name of the form attribute in the model.
* @see #getModelAttribute
*/
protected String getCommandName() {
return this.modelAttribute;
}

//other codes
}

IDEA 导入的 Maven 项目默认的 LanguageLeve l和 JavaCompiler 都是1.5,解决办法是在pom.xml中指定maven-compiler-plugin的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

reference: