搭建 Elasticsearch 单节点以及简单的使用教程

Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。 官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。 搭建 Elasticsearch 单节点以及简单的使用教程 接下来介绍如何本地搭建一个单节点的 Elasticsearch 服务器以及进行一些增删改查的简单操作。 安装 Elasticsearch 第一步:所需要的软件环境:最新稳定版 Java,若使用 docker 方式则不必安装 Java; 第二步:下载最新版 Elasticsearch; 第三步:解压下载的 Elasticsearch,建议位置选择一个用于存放数据的目录,磁盘剩余空间尽量留大一点; 第四步:运行 Elasticsearch,Linux 或者 macOS 运行 bin/Elasticsearch,Windows 运行 bin\Elasticsearch.bat; 第五步:使用命令 curl -X GET http://localhost:9200/ 检查运行状态,或者直接复制链接到浏览器中打开也可以, 正常情况下会显示以下类似的内容: { "name" : "DESKTOP-FHFP51P", "cluster_name" : "Elasticsearch", "cluster_uuid" : "lAdgnvl8TrmSrzRn321AKw", "version" : { "number" : "7.4.2", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96", "build_date" : "2019-10-28T20:40:44.881551Z", "build_snapshot" : false, "lucene_version" : "8.2.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } 使用 Elasticsearch 进行简单的操作 添加数据 curl -XPOST 'http://localhost:9200/twitter/_doc/?pretty' -H 'Content-Type: application/json' -d ' { "user": "kimchy", "post_date": "2009-11-15T13:12:00", "message": "Trying out Elasticsearch, so far so good?" }' 查找数据 curl -XGET 'http://localhost:9200/twitter/_search?pretty=true' -H 'Content-Type: application/json' -d ' { "query" : { "match_all" : {} } }' 修改数据 curl -XPUT 'http://localhost:9200/twitter/_doc/{ID}?pretty' -H 'Content-Type: application/json' -d ' { "user": "kimchy", "post_date": "2009-11-15T13:12:00", "message": "Trying out Elasticsearch, so far so good?" }' 删除数据(不建议直接删除) curl -XDELETE 'http://localhost:9200/twitter/_doc/{ID}?pretty'' 注意:上文中的{ID}为变量,具体要操作哪条数据应当传入数据的实际 ID Elasticsearch 性能测试 经过上文的教程,我们对 Elasticsearch 有了初步的了解以及学会了如何使用基本的操作,接下来我们测一下单节点的性能。 首先我们主要使用的是 ab 命令(Apache-Bench)进行压力测试,命令如下 ab -n100000 -c10 -p ./postfile.ab -T 'application/json' http://localhost:9200/twitter/_doc/?pretty=true 其中,postfile.ab 为我们需要发送给 Elasticsearch 的模拟数据,数据内容参考如下 { "user": "kimchy", "post_date": "2009-11-15T13:12:00", "message": "Trying out Elasticsearch, so far so good?" } 并发 10TPS 请求 10 万次 测试报告如下 This is ApacheBench, Version 2.3 <$Revision: 1807734 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Server Hostname: localhost Server Port: 9200 Document Path: /twitter/_doc/?pretty=true Document Length: 243 bytes Concurrency Level: 10 Time taken for tests: 28.107 seconds Complete requests: 10000 Failed requests: 5557 (Connect: 0, Receive: 0, Length: 5557, Exceptions: 0) Total transferred: 3815557 bytes Total body sent: 2860000 HTML transferred: 2435557 bytes Requests per second: 355.79 [#/sec] (mean) Time per request: 28.107 [ms] (mean) Time per request: 2.811 [ms] (mean, across all concurrent requests) Transfer rate: 132.57 [Kbytes/sec] received 99.37 kb/s sent 231.94 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 1 6 6.5 5 170 Processing: 6 21 19.5 17 529 Waiting: 4 17 17.4 13 527 Total: 11 28 21.7 23 534 Percentage of the requests served within a certain time (ms) 50% 23 66% 26 75% 29 80% 31 90% 41 95% 53 98% 79 99% 112 100% 534 (longest request) 通过 ab 的测试报告可以看出,单节点的 Elasticsearch 性能非常强悍,达到了 355.79 / 秒处理量,另外通过观测 JVM 的系统资源使用,也是比较低的水平。 并发 400TPS 请求 10 万次 接下来我们进行更高的并发测试 This is ApacheBench, Version 2.3 <$Revision: 1807734 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 10000 requests Completed 20000 requests Completed 30000 requests Completed 40000 requests Completed 50000 requests Completed 60000 requests Completed 70000 requests Completed 80000 requests Completed 90000 requests Completed 100000 requests Finished 100000 requests Server Software: Server Hostname: localhost Server Port: 9200 Document Path: /twitter/_doc/?pretty=true Document Length: 245 bytes Concurrency Level: 400 Time taken for tests: 209.947 seconds Complete requests: 100000 Failed requests: 0 Total transferred: 38300000 bytes Total body sent: 28600000 HTML transferred: 24500000 bytes Requests per second: 476.31 [#/sec] (mean) Time per request: 839.787 [ms] (mean) Time per request: 2.099 [ms] (mean, across all concurrent requests) Transfer rate: 178.15 [Kbytes/sec] received 133.03 kb/s sent 311.18 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 87 392 214.7 345 3133 Processing: 26 445 216.2 397 3697 Waiting: 25 300 188.6 265 2722 Total: 443 838 380.2 746 6498 Percentage of the requests served within a certain time (ms) 50% 746 66% 822 75% 884 80% 951 90% 1074 95% 1314 98% 1637 99% 2002 100% 6498 (longest request) 可以看出,并发量达到了 476.31 / 秒,JVM 的资源使用情况也没有发生大幅提升的情况,可以说是非常的稳定。 总结 Elasticsearch 单节点的性能已经非常强悍了,并且支持分布式提升更大的性能扩容,可以说是完全满足日常的需求已经高并发的需求。 另外我们可以将系统日志、网络日志、应用日志、业务日志等易产生大量数据的接入 Elasticsearch 进行统一的管理,这样既保证效率,也避免了日志分散、数量大无法维护等带来问题。 参考文献 Elasticsearch - Getting Started Elasticsearch - 维基百科,自由的百科全书 版权 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 原创作者:10086@xiaoi.me 发表于 Xiaoi’s Blog:https://blog.xiaoi.me 原文链接:https://blog.xiaoi.me/2019/11/12/elastic-search-get-start 扫码关注我,在线与我沟通、咨询 转载请保留原文链接以及版权信息

2019/11/12
articleCard.readMore

Nextcloud 解决 MySQL 没有支持 4 字节字符时报错: SQLSTATE[42000],解决办法

根据 Nextcloud 控制面板安全及设置警告,解决最后一个报警,不支持 4 字节的问题时,遇到该问题, 所使用的数据库为MySQL但没有对4字节字符的支持。为正确处理文件名或评论中使用的4字节字符(比如emoji表情),建议开启MySQL的4字节字符支持。详细信息请阅读相关文档页面。 本文撰写时所使用的版本:Nextcloud 16.0.4 问题过程 按照 Nextcloud 给出的文档需要需要进行一系列的修复,本文到最后一步执行以下命令时遇到问题: sudo -u www-data php occ maintenance:repair 异常截图: In AbstractMySQLDriver.php line 125: An exception occurred while executing 'ALTER TABLE `oc_systemtag_group` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;': SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes 经过研究,发现是因为使用 3 字节的 utf8 编码时,索引长度最大 767 可以存储 767/3 = 255 个字符。 但使用 utf8mb4 时,因为是 4 字节,索引最大长度 767 不变的情况下,最多可以存储 767/4 = 191 个字符。 于是排查了数据库相关的字段,发现比较多的字段使用了 varchar(255),经过手动处理后,上面的 repair 执行成功。 以下将修复过程中使用的 SQL 进行了汇总整理,遇到此问题时,可以直接执行以下 SQL,不必手动去修复。 ALTER TABLE `oc_addressbooks` MODIFY COLUMN `principaluri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id` MODIFY COLUMN `uri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `displayname`; ALTER TABLE `oc_authtoken` MODIFY COLUMN `token` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' AFTER `name`; ALTER TABLE `oc_calendarobjects` MODIFY COLUMN `uri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `calendardata`; ALTER TABLE `oc_calendars` MODIFY COLUMN `principaluri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`, MODIFY COLUMN `uri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `displayname`; ALTER TABLE `oc_calendarsubscriptions` MODIFY COLUMN `uri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`, MODIFY COLUMN `principaluri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `uri`; ALTER TABLE `oc_dav_shares` MODIFY COLUMN `principaluri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`, MODIFY COLUMN `type` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `principaluri`, MODIFY COLUMN `publicuri` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `resourceid`; ALTER TABLE `oc_login_flow_v2` MODIFY COLUMN `poll_token` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `started`, MODIFY COLUMN `login_token` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `poll_token`; ALTER TABLE `oc_migrations` MODIFY COLUMN `app` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL FIRST , MODIFY COLUMN `version` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `app`; ALTER TABLE `oc_mimetypes` MODIFY COLUMN `mimetype` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' AFTER `id`; ALTER TABLE `oc_systemtag_group` MODIFY COLUMN `gid` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `systemtagid`; ALTER TABLE `oc_trusted_servers` MODIFY COLUMN `url_hash` varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'sha1 hash of the url without the protocol' AFTER `url`; 总结 我们在设计数据库时,也应该注意此问题,utf8 的情况下索引字段最大 varchar(255),utf8mb4 的情况下索引最大 varchar(191)。我们可以修改 mysql.conf 最大索引长度,但不推荐这样做,这样会导致性能下降。我们应该尽量让索引字段低于限制,索引字段太长时,我们是不是应该考虑设计上有问题了? 版权 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 原创作者:10086@xiaoi.me 发表于 Xiaoi’s Blog:https://blog.xiaoi.me 原文链接:https://blog.xiaoi.me/2019/11/04/nextcloud-mysql-utf8mb4-error 扫码关注我,在线与我沟通、咨询 转载请保留原文链接以及版权信息

2019/11/4
articleCard.readMore

PHP 使用 curl 访问获取 https 网站的内容

遇到一个 PHP 获取 https 网站内容的问题,这里整理成博文供搭建参考。 需求是目前自己搭建了一个国外的博文网站,打算使用国内的服务器进行加速访问。 查阅了 PHP 相关资料之后,发现 PHP 的 get_file_contents 和 curl 均可以实现。 get_file_contents 能实现简单的,考虑到要实现 Header 等内容的获取和传输, 于是使用了 curl 实现。编码完成之后发现报以下错误信息: Exception 35: SSL connect error 面向搜索引擎解决 BUG,发现是因为 SSL 协议的问题,默认的情况下服务器端禁用了低版本的 SSL 协议, 于是我们需要指定 PHP 使用高版本的 SSL 协议请求服务器端(国外的博文网站)。 // 这是我的博客网站 $siteUrl = 'https://blog.xiaoi.me'; function httpGet($url) { try { $ch = curl_init(); if (FALSE === $ch) throw new Exception('failed to initialize'); curl_setopt($ch,CURLOPT_URL, $url); // 这里为关键代码,经过几次测试只有,发现需要调整到 6 以上,具体可参考博文底部链接 curl_setopt($ch, CURLOPT_SSLVERSION, 6); $content = curl_exec($ch); if (FALSE === $content) throw new Exception(curl_error($ch), curl_errno($ch)); var_dump($content); } catch(Exception $e) { echo 'Exception ' . $e->getCode() . ': ' . $e->getMessage(); } } echo httpGet($siteUrl . $_GET['uri']); 通过使用以上的 PHP 代码即可完成基本的加速访问,原来使用 https://blog.xiaoi.me/a/b/c.html`` 访问的内容, 可以通过 PHP 加速访问,例如:proxy.php?uri=/a/b/c.html``` 总结 低版本 SSL 协议安全性很低,建议将自己的网站等应用禁用低版本 SSL 协议,并且有类似本文这样的需求时, 同时也将客户端的 SSL 协议版本提高,这样保证数据安全以及代码可用性。 参考文献 PHP: curl_setopt - Manual 版权 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 原创作者:10086@xiaoi.me 发表于 Xiaoi’s Blog:https://blog.xiaoi.me 原文链接:https://blog.xiaoi.me/2019/10/31/php-curl-ssl 扫码关注我,在线与我沟通、咨询 转载请保留原文链接以及版权信息

2019/10/31
articleCard.readMore

使用 ngrok 内网穿透工具

ngrok 微信开发必备神器,ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。QQ群:619152722 使用 下载客户端,解压之后运行 start.bat,默认 8080 可直接通过生成的随机域名访问。 若本地非 8080 端口,右键编辑 start.bat 文件,将最后的 8080 换成指定端口,例如 80 即可。 若需要固定域名例如: test ,修改内容:ngrok -config ngrok.cfg --subdomain test 8080,访问时通过:http://test.4kb.cn(或者:https://test.4kb.cn 加密访问) 即可。 如果无法连接服务器,请使用命令 ping ngrok.4kb.cn 检查 IP 是否为 112.124.46.214,若不是,请手动绑定 HOSTS,若不知道如何绑定 HOSTS,请善用搜索引擎 下载 64 位系统 Windows 客户端 Linux 客户端 Mac 客户端 32 位系统 Windows 客户端(32位) Linux 客户端(32位) Mac 客户端(32位)

2019/10/23
articleCard.readMore

使用 docker 运行 frp 服务端,并且上传到 docker hub 在线仓库

最近在使用 frp 内网穿透服务,运行了一段时间,发现 frp 挺稳定的,突发奇想,之前学习了一下 docker 的使用,何不把 frp 打包成 docker 镜像,这样在任意服务器上就能快速开启 frp 服务了,于是折腾了一下午总算是搞定了。 如果不想自己配置,可以使用 docker run -p 7000:7000 xiaoi/frp_for_docker:0.27.0 命令直接运行已经打包好的镜像。若要修改配置,覆盖镜像中的 /app/frps.ini 配置文件即可。 操作步骤 下载和配置 frp 首先我们需要下载一个 frp 服务端程序,可以在 github.com 上下载到最新发布的版本,这里下载 frp_0.27.0_linux_386.tar.gz 版本作为演示。 下载好了之后解压得到相关的应用程序和配置文件,我们只需要保留 frps 和 frps.ini 即可。若有需要可以在 frps.ini 进行自定义配置。 Dockerfile 编写 接下来我们编写 Dockerfile 文件,由于 frp 使用 golang 开发,发布的版本可以直接在 alpine 环境下运行,于是我们的工作变得非常简单,按照如下的代码编写即可 FROM alpine:latest WORKDIR /app COPY . /app EXPOSE 7000 CMD ["./start.sh"] 由于我在 frps.ini 中配置的 7000 端口,这里 EXPOSE 也设置 7000 端口保持一致。 CMD 这里填写 "./start.sh"方便启动,start.sh 内容如下 #!/bin/sh ./frps -c ./frps.ini docker 命令打包镜像 编写好 Dockerfile 和启动脚本之后,我们就可以使用 docker 命令打包了 docker build --tag=frp_for_docker . 打包好了之后使用 docker image ls 查看打包好的镜像 运行和检查镜像 使用 docker run -p 7000:7000 frp_for_docker 运行我们打包好的镜像,出现 success 等字样信息表明运行成功 上传镜像至在线仓库 如果想要在任意地方都能运行我们打包好的镜像,则需要上传镜像至 hub.docker.com 在线仓库,上传之前需要 注册 docker 账号 注册好了之后回到控制台运行 docker login 然后输入账号密码登录 然后将我们的镜像改名,格式为 用户名/镜像名:版本号 ,例如我的用户名为 xiaoi,镜像名我定义为 frp_for_docker ,版本号我这里按照 frp 版本号来定义,其中除了用户名不能自定义,镜像名和版本号都是可以任意命名,使用如下命令将本地镜像改名。 docker tag frp_by_docker xiaoi/frp_by_docker:0.27.0 改好之后使用 docker push 命令上传至在线仓库 docker push xiaoi/frp_for_docker:0.27.0 上传完成之后我们就可以在 hub.docker.com 在线仓库中查看我们的镜像了 在别处直接运行在线仓库中的镜像 在有 docker 环境的服务器或者个人电脑上使用 docker run 命令就可以运行在线仓库中的镜像,例如运行我们上传的镜像 docker run -p 7000:7000 xiaoi/frp_for_docker:0.27.0 运行命令之后,接下来的这一切都是自动化完成的,无需我们再做任何操作 总结 使用 docker 我们可以很容易的将一个应用程序分发到各个地方运行,便于后期的维护和管理,同时也不用担心跨平台的问题产生; 程序所依赖的环境我们也可以通过编写 Dockerfile 来解决,不必再为各个环境依赖重复安装运行环境,这样极大的减轻来工作量; docker 能运行的程序远不于此,我们可以将所熟悉的一切软件都使用 docker 来运行和管理; 版权 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 原创作者 10086@xiaoi.me 发表于阿里云·云栖社区:https://yq.aliyun.com/users/y4epujtm5wye6 扫码关注我,在线与我沟通、咨询 转载请保留原文链接以及版权信息

2019/10/23
articleCard.readMore

CentOS 7 下搭建自己的 ngrok 内网穿透服务

现在的家庭宽带或者部分公司的宽带都没有直接分配公网 IP ,这个给我们做开发调试时带来的很大的不便,比如我们需要对接微信公众号、支付宝等第三方系统时,第三方系统需要通过异步回调通知我们的服务,但是我们自己电脑上的应用程序都无法对外访问,这样也就通知不了,无法很好的进行联调测试。 在这样的背景下,ngrok 对于我们来说就提供了很大的帮助,他可以让我们内网的应用可以对外访问,无论是 HTTP(s) 服务还是 TCP/SSH 等场景,均可以通过 ngrok 服务内网穿透来达到对外提供访问的目的。 搭建步骤 第一步:安装 golang 环境 博主的服务器统一使用的 CentOS 7 发行版本,所以通过 yum install golang 就可以安装好 golang 环境,如果是其他操作系统可以参考官方文档 How to install golang 第二步:下载 ngrok 源码 目前 ngrok 2.x 版本已经闭源,我们能下载到的最新版本为 ngrok-1.7.1.zip, 下载完成之后解压 zip 包,这里我们需要修改 src/ngrok/log/logger.go 中的源代码, 将 log "code.google.com/p/log4go" 修改为 log "github.com/alecthomas/log4go", 否则编译时会报错 build fails: 'package code.google.com/p/log4go: unable to detect version control system for code.google.com/ path' 第三步:生成 TLS 证书 例如我们以 4kb.cn 域名为例,我们在生成证书的时候可以指定 ngrok.4kb.cn 这个域名指定 ngrok 服务器地址(需要 DNS 解析到 ngrok 所在服务器的 IP 上),同时我们对外提供 ngrok 域名为 *.4kb.cn (需要泛域名解析 *.4kb.cn 到 ngrok 所在服务器的 IP 上),这里的 ngrok.4kb.cn 和 *.4kb.cn 解析并不冲突。 生成 TLS 证书的命令如下: openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=ngrok.4kb.cn" -days 3650 -out rootCA.pem openssl genrsa -out device.key 2048 openssl req -new -key device.key -subj "/CN=ngrok.4kb.cn" -out device.csr openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 3650 第四步:覆盖 ngrok 默认 TLS 证书 cp rootCA.pem assets/client/tls/ngrokroot.crt cp device.crt assets/server/tls/snakeoil.crt cp device.key assets/server/tls/snakeoil.key 第五步:设置 Golang 编译目录和参数 export GOPATH=/go 为了可以在 docker 环境下运行,我们还需要运行下面的命令,否则会报错 Unable to run a go program inside docker /bin/sh: ./ngrokd: not found export CGO_ENABLED=0 第六步:编译 ngrok 服务端和客户端 Linux 32 位系统 ngrok 编译命令 export GOOS=linux GOARCH=386 make release-server release-client Linux 64 位系统 ngrok 编译命令 export GOOS=linux GOARCH=amd64 make release-server release-client Windows 32 位系统 ngrok 编译命令 export GOOS=windows GOARCH=386 make release-server release-client Windows 64 位系统 ngrok 编译命令 export GOOS=windows GOARCH=amd64 make release-server release-client macOS 32 位系统 ngrok 编译命令 export GOOS=darwin GOARCH=386 make release-server release-client macOS 64 位系统 ngrok 编译命令 export GOOS=darwin GOARCH=amd64 make release-server release-client 其他操作系统修改 GOOS 和 GOARCH 为对应的即可:Go (Golang) GOOS and GOARCH 第七步:运行 ngrokd 服务端 编译完成之后可以在 bin 目录下看到 ngrokd(服务端)和 ngrok(客户端),运行服务端时需要将 assets/server/tls/snakeoil.crt 和 assets/server/tls/snakeoil.key 复制到同级目录,启动的命令参考如下: ./ngrokd -tlsKey=snakeoil.key -tlsCrt=snakeoil.crt -domain="4kb.cn" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443" 如果使用默认 80、443、4443 端口,则可以使用以下命令运行: ./ngrokd -tlsKey=snakeoil.key -tlsCrt=snakeoil.crt -domain="4kb.cn" 第八步:运行 ngrok 客户端 运行之前我们需要编写一个 ngrok.cfg 文件,内容如下 server_addr: "ngrok.4kb.cn:4443" trust_host_root_certs: false 这里的 server_addr 需要和第三步生成 TLS 时保持一致,否则服务端会报 tls: bad certificate 证书错误, 编辑完成之后使用 ngrok 客户端运行即可 ./ngrok -config=ngrok.cfg 8080 指定域名运行命令 ./ngrok -config=ngrok.cfg -subdomain=xxx 8080 映射 SSH 22 端口,使用 tcp 协议 ./ngrok -config=ngrok.cfg -proto=tcp 22 总结 我们搭建完成 ngrok 服务端后,任意能连接到服务器的应用程序均可以通过 ngrok 内网穿透,不仅 Java、PHP 等开发的网站可以通过 ngrok 映射对外提供域名访问,也可以让 SSH 的 22 端口映射之后,我们连接无公网 IP 的服务器(比如在家里面搭建一个私有服务器),甚至还可以将 MySQL 的 3306 端口映射之后,在任意地点远程连接内网的数据库。这给我们带来来极大的方便,也不需要购买第三方服务(例如花生壳)。 参考文献 编译自己的ngrok服务 Go (Golang) GOOS and GOARCH Unable to run a go program inside docker /bin/sh: < program>: not found 版权 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证) 原创作者 10086@xiaoi.me 发表于阿里云·云栖社区:https://yq.aliyun.com/users/y4epujtm5wye6 扫码关注我,在线与我沟通、咨询 转载请保留原文链接以及版权信息

2019/10/23
articleCard.readMore

手机型号数据库

有时候我们遇到获取用户的手机型号时,只能获取 XX-XXX 这样的型号,我们无法直接得知用户的手机名称,在网上各大数据接口上搜寻了一番也未找到一种可以直接将手机型号(例如:SM901)转换为人类可直接阅读的名称(例如:锤子 M1),于是我和另外一个小伙伴(51587124@github)发起了该项目。 该项目的主旨为提供一个统一、公开、人人可参与的手机型号数据库,采用 github 进行托管和维护,同时我个人提供了基于该数据库实现的在线 API ,大家也可以基于该数据库文件实现私有的 API,定期同步数据库文件即可。 若在使用的过程中有缺失的机型信息,欢迎提交 issues 存储格式 model:name:brand 在线 API 正常状态返回 0,name 为手机名称,brand 为手机品牌 https://model-lib.4kb.cn/api/model/{model} example: https://model-lib.4kb.cn/api/model/SM901 版权信息 原作者 weibo@@KHwang9883 修改者 10086@xiaoi.me,整合了原作者的数据为标准格式,并提供在线 API 许可 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 文档版的分发和传播亦适用于该协议。 参考文献 手机品牌型号汇总

2019/10/23
articleCard.readMore

IntelliJ Idea 常用快捷键列表

File - Settings - Keymap 可以修改快捷键绑定,建议将默认的关闭当前 Tab 标签修改为 Ctrl+W 键(路径:Main menu - Window - Editor Tabs - Close)这样可以编辑完当前文件之后直接 Ctrl+W 关闭,一是可以减少 Tab 标签数量,二是可以确认自己的代码已经保存过了(未保存时会提示保存),同时也可以避免手误把已经改好的代码改错或者撤回之类的误操作。 快捷键列表 Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如get,set方法,构造函数等) Ctrl+E或者Alt+Shift+C 最近更改的代码 Ctrl+R 替换文本 Ctrl+F 查找文本 Ctrl+Shift+Space 自动补全代码 Ctrl+空格 代码提示 Ctrl+Alt+方向左、Ctrl+Alt+方向右,可以在最近几次编辑的位置之间切换 Ctrl+Alt+Space 类名或接口名提示 Ctrl+P 方法参数提示 Ctrl+Shift+Alt+N 查找类中的方法或变量 Alt+Shift+C 对比最近修改的代码 Shift+F6 重构-重命名 Ctrl+Shift+先上键 Ctrl+X 删除行 Ctrl+D 复制行 Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者/…/ ) Ctrl+J 自动代码 Ctrl+E 最近打开的文件 Ctrl+H 显示类结构图 Ctrl+Q 显示注释文档 Alt+F1 查找代码所在位置 Alt+1 快速打开或隐藏工程面板 Ctrl+Alt+ left/right 返回至上次浏览的位置 Alt+ left/right 切换代码视图 Alt+ Up/Down 在方法间快速移动定位 Ctrl+Shift+Up/Down 代码向上/下移动。 F2 或Shift+F2 高亮错误或警告快速定位 代码标签输入完成后,按Tab,生成代码。 选中文本,按Ctrl+Shift+F7 ,高亮显示所有该文本,按Esc高亮消失。 Ctrl+W 选中代码,连续按会有其他效果 选中文本,按Alt+F3 ,逐个往下查找相同文本,并高亮显示。 Ctrl+Up/Down 光标跳转到第一行或最后一行下 Ctrl+B 快速打开光标处的类或方法 最常用快捷键 Ctrl+E,可以显示最近编辑的文件列表 Shift+Click可以关闭文件 Ctrl+[或]可以跳到大括号的开头结尾 Ctrl+Shift+Backspace可以跳转到上次编辑的地方 Ctrl+F12,可以显示当前文件的结构 Ctrl+F7可以查询当前元素在当前文件中的引用,然后按F3可以选择 Ctrl+N,可以快速打开类 Ctrl+Shift+N,可以快速打开文件 Alt+Q可以看到当前方法的声明 Ctrl+W可以选择单词继而语句继而行继而函数 Alt+F1可以将正在编辑的元素在各个面板中定位 Ctrl+P,可以显示参数信息 Ctrl+Shift+Insert可以选择剪贴板内容并插入 Alt+Insert可以生成构造器/Getter/Setter等 Ctrl+Alt+V 可以引入变量。例如把括号内的SQL赋成一个变量 Ctrl+Alt+T可以把代码包在一块内,例如try/catch Alt+Up and Alt+Down可在方法间快速移动 下面的不是很有用 在一些地方按Alt+Enter可以得到一些Intention Action,例如将”==”改为”equals()” Ctrl+Shift+Alt+N可以快速打开符号 Ctrl+Shift+Space在很多时候都能够给出Smart提示 Alt+F3可以快速寻找 Ctrl+/和Ctrl+Shift+/可以注释代码 Ctrl+Alt+B可以跳转到抽象方法的实现 Ctrl+O可以选择父类的方法进行重写 Ctrl+Q可以看JavaDoc Ctrl+Alt+Space是类名自动完成 快速打开类/文件/符号时,可以使用通配符,也可以使用缩写 Live Templates! Ctrl+J Ctrl+Shift+F7可以高亮当前元素在当前文件中的使用 Ctrl+Alt+Up /Ctrl+Alt+Down可以快速跳转搜索结果 Ctrl+Shift+J可以整合两行 Alt+F8是计算变量值 IntelliJ IDEA使用技巧一览表 在使用 InelliJ IDEA 的过程中,通过查找资料以及一些自己的摸索,发现这个众多 Java 程序员喜欢的 IDE 里有许多值得一提的小窍门,如果能熟练的将它们应用于实际开发过程中,相信它会大大节省你的开发时间,而且随之而来的还会有那么一点点成就感:) Try it ! 1 、写代码时用 Alt-Insert ( Code|Generate… )可以创建类里面任何字段的 getter 与 setter 方法。 <?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” /> 2 、右键点击断点标记(在文本的左边栏里)激活速查菜单,你可以快速设置 enable/disable 断点或者条件它的属性。 3 、 CodeCompletion (代码完成)属性里的一个特殊的变量是,激活 Ctrl-Alt-Space 可以完成在或不在当前文件里的类名。如果类没有引入则 import 标志会自动创建。 4 、使用 Ctrl-Shift-V 快捷键可以将最近使用的剪贴板内容选择插入到文本。使用时系统会弹出一个含有剪贴内容的对话框,从中你可以选择你要粘贴的部分。 5 、利用 CodeCompletion (代码完成)属性可以快速地在代码中完成各种不同地语句,方法是先键入一个类名地前几个字母然后再用 Ctrl-Space 完成全称。如果有多个选项,它们会列在速查列表里。 6 、用 Ctrl-/ 与 Ctrl-Shift-/ 来注释 / 反注释代码行与代码块。 -/ 用单行注释标记(“ //… ”)来注释 / 反注释当前行或者选择地代码块。而 Ctrl-Shift-/ 则可以用块注释标记(“ /…/ ”)把所选块包围起来。要反注释一个代码块就在块中任何一个地方按 Ctrl-Shift-/ 即可。 7 、按 Alt-Q ( View|Context Info )可以不需要移动代码就能查看当前方法地声明。连续按两次会显示当前所编辑的类名。 8 、使用 Refactor|Copy Class… 可以创建一个所选择的类的“副本”。这一点很有用,比如,在你想要创建一个大部分内容都和已存在类相同的类时。 9 、在编辑器里 Ctrl-D 可以复制选择的块或者没有所选块是的当前行。 10 、 Ctrl-W (选择字)在编辑器里的功能是先选择脱字符处的单词,然后选择源代码的扩展区域。举例来说,先选择一个方法名,然后是调用这个方法的表达式,然后是整个语句,然后包容块,等等。 11 、如果你不想让指示事件细节的“亮球”图标在编辑器上显示,通过按 Alt-Enter 组合键打开所有事件列表然后用鼠标点击它就可以把这个事件文本附件的亮球置成非活动状态。 这样以后就不会有指示特殊事件的亮球出现了,但是你仍然可以用 Alt-Enter 快捷键使用它。 12 、在使用 CodeCompletion 时,可以用逗点( . )字符,逗号(,)分号(;),空格和其它字符输入弹出列表里的当前高亮部分。选择的名字会随着输入的字符自动输入到编辑器里。 13 、在任何工具窗口里使用 Escape 键都可以把焦点移到编辑器上。 Shift-Escape 不仅可以把焦点移到编辑器上而且还可以隐藏当前(或最后活动的)工具窗口。 F12 键把焦点从编辑器移到最近使用的工具窗口。 14 、在调试程序时查看任何表达式值的一个容易的方法就是在编辑器中选择文本(可以按几次 Ctrl-W 组合键更有效地执行这个操作)然后按 Alt-F8 。 15 、要打开编辑器脱字符处使用的类或者方法 Java 文档的浏览器,就按 Shift-F1 (右键菜单的 External JavaDoc )。 要使用这个功能须要把加入浏览器的路径,在“ General ”选项中设置( Options | IDE Settings ),另外还要把创建的 Java 文档加入到工程中( File | Project Properties )。 16 、用 Ctrl-F12 ( View | File Structure Popup )键你可以在当前编辑的文件中快速导航。 这时它会显示当前类的成员列表。选中一个要导航的元素然后按 Enter 键或 F4 键。要轻松地定位到列表中的一个条目,只需键入它的名字即可。 17 、在代码中把光标置于标记符或者它的检查点上再按 Alt-F7 (右键菜单中的 Find Usages… )会很快地查找到在整个工程中使用地某一个类、方法或者变量的位置。 18 、按 Ctrl-N ( Go to | Class… )再键入类的名字可以快速地在编辑器里打开任何一个类。从显示出来的下拉列表里选择类。 同样的方法你可以通过使用 Ctrl-Shift-N ( Go to | File… )打开工程中的非 Java 文件。 19 、要导航代码中一些地方使用到的类、方法或者变量的声明,把光标放在查看项上再按 Ctrl-B 即可。也可以通过按 Ctrl 键的同时在查看点上单击鼠标键调转到声明处。 20 、把光标放到查看点上再按 Ctrl-Alt-B 可以导航到一个抽象方法的实现代码。 21 、要看一个所选择的类的继承层次,按 Ctrl-H ( Browse Type Hierarchy )即可。也可以激活编辑器中的继承关系视图查看当前编辑类的继承关系。22 、使用 Ctrl-Shift-F7 ( Search | Highlight Usages in File )可以快速高亮显示当前文件中某一变量的使用地方。按 Escape 清除高亮显示。 23 、用 Alt-F3 ( Search | Incremental Search )在编辑器中实现快速查查找功能。 在“ Search for: ”提示工具里输入字符,使用箭头键朝前和朝后搜索。按 Escape 退出。 24 、按 Ctrl-J 组合键来执行一些你记不起来的 Live Template 缩写。比如,键“ it ”然后按 Ctrl-J 看看有什么发生。 25 、 Introduce Variable 整合帮助你简化代码中复杂的声明。举个例子,在下面的代码片断里,在代码中选择一个表达式:然后按 Ctrl-Alt-V 。 26 、 Ctrl-Shift-J 快捷键把两行合成一行并把不必要的空格去掉以匹配你的代码格式。 27 、 Ctrl-Shift-Backspace ( Go to | Last Edit Location )让你调转到代码中所做改变的最后一个地方。 多按几次 Ctrl-Shift-Backspace 查看更深的修改历史。 28 、用 Tools | Reformat Code… 根据你的代码样式参考(查看 Options | IDE Setting | Code Style )格式化代码。 使用 Tools | Optimize Imports… 可以根据设置(查看 Options | IDE Setting | Code Style | Imports )自动“优化” imports (清除无用的 imports 等)。 29 、使用 IDEA 的 Live Templates | Live Templates 让你在眨眼间创建许多典型代码。比如,在一个方法里键入 再按 Tab 键看有什么事情发生了。 用 Tab 键在不同的模板域内移动。查看 Options | Live Templates 获取更多的细节。 30 、要查看一个文件中修改的本地历史,激活右键菜单里的 Local VCS | Show History… 。也许你可以导航不同的文件版本,看看它们的不同之处再回滚到以前的任何一个版本吧。 使用同样的右键菜单条目还可以看到一个目录里修改的历史。有了这个特性你就不会丢失任何代码了。 31 、如果要了解主菜单里每一个条目的用途,把鼠标指针移到菜单条目上再应用程序框架的底部的状态栏里就会显示它们的一些简短描述,也许会对你有帮助。 32 、要在编辑器里显示方法间的分隔线,打开 Options | IDE Settings | Editor ,选中“ Show method separators ”检查盒( checkbox )。 33 、用 Alt-Up 和 Alt-Down 键可以在编辑器里不同的方法之间快速移动。 34 、用 F2/Shift-F2 键在高亮显示的语法错误间跳转。 用 Ctrl-Alt-Down/Ctrl-Alt-Up 快捷键则可以在编译器错误信息或者查找操作结果间跳转。 35 、通过按 Ctrl-O ( Code | Override Methods… )可以很容易地重载基本类地方法。 要完成当前类 implements 的(或者抽象基本类的)接口的方法,就使用 Ctrl-I ( Code | Implement Methods… )。 36 、如果光标置于一个方法调用的括号间,按 Ctrl-P 会显示一个可用参数的列表。 37 、要快速查看编辑器脱字符处使用的类或方法的 Java 文档,按 Ctrl-Q (在弹出菜单的 Show Quick JavaDoc 里)即可。 38 、像 Ctrl-Q ( Show Quick JavaDoc 显示简洁 Java 文档), Ctrl-P ( Show Parameter Info 显示参数信息), Ctrl-B ( Go to Declaration 跳转到声明), Shift-F1 ( External JavaDoc 外部 Java 文档)以及其它一些快捷键不仅可以在编辑器里使用,也可以应用在代码完成右键列表里。 39 、 Ctrl-E ( View | Recent Files )弹出最近访问的文件右键列表。选中文件按 Enter 键打开。 40 、在 IDEA 中可以很容易地对你的类,方法以及变量进行重命名并在所有使用到它们的地方自动更正。 试一下,把编辑器脱字符置于任何一个变量名字上然后按 Shift-F6 ( Refactor | Rename… )。在对话框里键入要显示地新名字再按 Enter 。你会浏览到使用这个变量地所有地方然后按“ Do Refactor ”按钮结束重命名操作。 41 、要在任何视图( Project View 工程视图, Structure View 结构视图或者其它视图)里快速 选择当前编辑地部分(类,文件,方法或者字段),按 Alt-F1 ( View | Select in… )。 42 、在“ new ”字符后实例化一个已知类型对象时也许你会用到 SmartType 代码完成这个特性。比如,键入 再按 Ctrl-Shift-Space : 43 、通过使用 SmartType 代码完成,在 IDEA 中创建接口的整个匿名 implementation 也是非常容易的,比如,对于一些 listener (监听器),可以键入 Component component; component.addMouseListener( new ); 然后再按 Ctrl-Shift-Space 看看有什么发生了。 44 、在你需要设置一个已知类型的表达式的值时用 SmartType 代码完成也很有帮助。比如,键入 String s = ( 再按 Ctrl-Shift-Space 看看会有什么出现。 45 、在所有视图里都提供了速查功能:在树里只需键入字符就可以快速定位到一个条目。 46 、当你想用代码片断捕捉异常时,在编辑器里选中这个片断,按 Ctrl-Alt-T ( Code | Surround with… )然后选择“ try/catch ”。它会自动产生代码片断中抛出的所有异常的捕捉块。在 Options | File Templates | Code tab 中你还可以自己定制产生捕捉块的模板。 用列表中的其它项可以包围别的一些结构。 47 、在使用代码完成时,用 Tab 键可以输入弹出列表里的高亮显示部分。 不像用 Enter 键接受输入,这个选中的名字会覆盖掉脱字符右边名字的其它部分。这一点在用一个方法或者变量名替换另一个时特别有用。 48 、在声明一个变量时代码完成特性会给你显示一个建议名。比如,开始键入“ private FileOutputStream ”然后按 Ctrl-Space 参考文章 IntelliJ Idea 常用快捷键列表

2019/10/23
articleCard.readMore

欢迎使用 Frp 内网穿透服务

近期收到部分群友反馈,ngrok 服务偶尔会出现无法连接、访问缓慢、客户端闪退等情况,群主决定研究一下如何搭建 frp 服务,经过一下午的时间,总算搭建好了 frp 服务,现在将 frp 服务公开给群友供大家使用。 目前客户端只打包了 windows,其他操作系统的群友可以在 frp 官方下载对应的客户端,目前服务端使用的 0.27.0 版本,客户端尽量使用相同版本:https://github.com/fatedier/frp/releases/tag/v0.27.0 windows 客户端下载地址:https://img.xiaoi.me/pms-upload/20190605/15a82187-d4b8-e1f9-371b-5113463b57f0.zip 另外,服务器提供了更多“黑科技”服务,欢迎大家的使用和咨询。 若对群主提供的服务满意,还请捐赠支持一下:https://tb.4kb.cn

2019/10/22
articleCard.readMore

Docker 容器化服务笔记

容器化服务笔记 安装和启用 docker > yum install docker > systemctl enable docker.service > systemctl start docker.service 1、运行时时区设置问题: FROM openjdk:8-jdk-alpine RUN apk add --no-cache tzdata ENV TZ Asia/Shanghai RUN date -R 运行时字体加载失败:NPE at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264) RUN apk add --no-cache fontconfig 2、进入容器执行 bash 命令 container id 不用输全 docker exec -t -i {container id} /bin/bash 查询日志 docker logs 9573ada 服务的方式 docker 运行 nginx sudo docker run --name my-nginx -p 80:80 -v /Users/stevenkang-mac/docker-nginx/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx 打包镜像命令 mvn clean package docker:build -D maven.test.skip=true 打包并上传镜像 mvn clean package docker:build -DpushImage -D maven.test.skip=true docker-maven-plugin 无法推送时,清除 ~/.docker/config.json 中的 autos 配置信息后重拾 Failed to push registry MySQL 容器化运行 > docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag > docker run --rm --name mysql -v /var/lib/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pwd -p 3306:3306 -d mysql:5.7 > docker run --rm --name mysql -v /var/lib/mysql:/var/lib/mysql -p 3306:3306 -d mysql:5.6 > sudo docker run --rm --name mysql -v /Users/stevenkang-mac/mysql:/var/lib/mysql -p 3306:3306 -m 256m --memory-swap=512m -d mysql:5.6 Spring Config Server 容器化运行 > docker run —rm --name config-server -p 192.168.1.145:8888:8888 -v /etc/spring/config_server-application.yml:/application.yml -d springcloud/configserver Redis 容器化运行 > docker run --name redis -d redis:4-alpine > docker run --name redis -p 6379:6379 -d --rm redis --requirepass "password" Nginx 容器化运行 > docker run --name my-nginx -v /etc/nginx.conf:/etc/nginx/nginx.conf:ro -v /etc/nginx:/v-nginx -p 80:80 -p 443:443 --rm -d nginx 编译 kms 服务:Dockerfile FROM alpine:latest RUN echo 'https://mirrors.aliyun.com/alpine/latest-stable/main/' > /etc/apk/repositories \ && echo 'https://mirrors.aliyun.com/alpine/latest-stable/community/' >> /etc/apk/repositories \ && apk update \ && apk upgrade \ && apk add --no-cache build-base gcc abuild binutils cmake git \ && cd / \ && git clone https://github.com/Wind4/vlmcsd.git vlmgit \ && cd vlmgit \ && make \ && chmod +x bin/vlmcsd \ && mv bin/vlmcsd / \ && cd / \ && apk del build-base gcc abuild binutils cmake git \ && rm -rf /vlmgit \ && rm -rf /var/cache/apk/* EXPOSE 1688 CMD ["/vlmcsd", "-D", "-d", "-t", "3", "-e", "-v"] 阿里云日志服务 > docker pull registry.cn-hangzhou.aliyuncs.com/log-service/logtail > docker run -d -v /:/logtail_host:ro -v /var/run/docker.sock:/var/run/docker.sock --env ALIYUN_LOGTAIL_CONFIG=/etc/ilogtail/conf/cn-hangzhou/ilogtail_config.json --env ALIYUN_LOGTAIL_USER_ID=1553473*******38 --env ALIYUN_LOGTAIL_USER_DEFINED_ID=userdefined registry.cn-hangzhou.aliyuncs.com/log-service/logtail 参考文献 Docker 官方使用指南 Github: docker-nginx issues #92 Docker 官方镜像之 Nginx Docker 官方镜像之 MySQL A Maven plugin for building and pushing Docker images.

2019/10/22
articleCard.readMore