利用Docker搭建Elasticsearch和Kibana版本7.4.2(Mac)

最近公司技术部门发福利,给技术部小伙伴买了一些技术教程视频和书籍,考虑到App使用全文搜索功能,购买了Elasticsearch入门视频。

这篇文章记录一下使用Docker搭建本机测试用elasticsearch和网页图形工具kibana

当前elasticsearch和kibana的最新版本是7.4.2,使用命令拉取最新两个镜像:

docker pull elasticsearch:7.4.2
docker pull kibana:7.4.2

花费半小时拉取完毕之后(网速看脸,有时候快有时候慢),两个官方镜像就已经准备好了。

首先创建一下elasticsearch和kibana专用的docker网络:

docker network create --subnet=172.20.0.0/16 es

创建elasticsearch运行容器:

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v /Users/charles/docker/elasticsearch/data:/usr/share/elasticsearch/data --network es --ip 172.20.0.2 elasticsearch:7.4.2

上述命令中 /Users/charles/docker/elasticsearch/data 是elasticsearch存放索引数据的文件夹,换成你觉得方便的地方。设置固定ip方便设置kibana

防止遇到一些未知的错误,我建议你把上述命令中的-d参数去掉,不使用daemon方式运行,直接以前台运行,看到下图则表明elasticsearch运行正常,再加上-d作为后台服务运行

打开http://127.0.0.1:9200/测试一下是否运行正常

看到类似上图一样的JSON串说明elasticsearch运行正常。上图使用了Chrome的格式化JSON串插件,科学上网后点击此链接安装

接下来安装kibana客户端工具,使用命令获取elasticserach容器的虚拟内网ip地址

docker inspect elasticsearch | grep IPAddress
配图仅供参考

我的docker上显示的是 172.20.0.2,根据此IP地址启动kibana容器

docker run --network es --name kibana -e ELASTICSEARCH_URL=http://172.20.0.2:9200 -p 5601:5601 -d kibana:7.4.2

执行好此命令后,可以在浏览器打开http://127.0.0.1:5601

如果页面提示:Kibana server is not ready yet,稍等片刻再重试

见到上图,则说明kibana已经正常运行了。

可以使用命令,让elasticsearch、kibana在docker运行时自动启动,参考链接

docker update --restart=always elasticsearch
docker update --restart=always kibana

尽情享用elasticsearch吧

Xshell不能使用退格、删除键的解决方案

xshell使用中,若是敲错字母了的,按退键删除敲错的字母,却正在屏幕表现出了“^H”,无法正常删除,再按删除键,却表现出“^[[3~”

修改办法:当前连接属性–>终端 –>键盘 把delete 和backspace序列改为 ASCII 127即可。

Laravel/Lumen漂亮的解决主从库延迟问题

5.5及以上版本:

// 修改config/database.php文件
// 增加sticky配置项为true
'mysql' => [
	'driver' => 'mysql',
	'host' => env('DB_HOST', '127.0.0.1'),
	'port' => env('DB_PORT', '3306'),
	'database' => env('DB_DATABASE', 'forge'),
	'username' => env('DB_USERNAME', 'forge'),
	'password' => env('DB_PASSWORD', ''),
	'unix_socket' => env('DB_SOCKET', ''),
	'charset' => 'utf8mb4',
	'collation' => 'utf8mb4_general_ci',
	'prefix' => '',
	'prefix_indexes' => true,
	'strict' => true,
	'engine' => null,
	'sticky' => true,
],

5.4及以下版本:

app/Providers/AppServiceProvider增加boot方法,监听每条执行的SQL,如果发现DML语句(INSERT,UPDATE,DELETE)时,则清空从库连接的pdo(readPdo),这样由于Laravel底层安全机制,会默认使用主库连接。这样没有使用事务时,从根本上解决执行DML语句后,再执行DQL(SELECT)语句的延迟问题。

// Laravel/Lumen Connection源码,当readPdo为null时,默认使用主库pdo实例。
public function getReadPdo()
{
     if ($this->transactions >= 1) {
            return $this->getPdo();
     }
      return $this->readPdo ?: $this->pdo;
}

Laravel/Lumen 5.1 实现代码

public function boot()
{
    \DB::listen(function ($sql, $bindings, $time, $connection) {
          $sql = ltrim($sql);
          if (stripos($sql, 'insert') === 0
                   || stripos($sql, 'update') === 0
                    || stripos($sql, 'delete') === 0
           ) {
                 //清空从库连接, 自动使用主库连接
                 \DB::connection($connection)->setReadPdo(null);
           }
     });
}

Laravel/Lumen 5.2 实现代码

public function boot()
{
     \DB::listen(function (QueryExecuted $executed) {
                $executed->sql = ltrim($executed->sql);
                if (stripos($executed->sql, 'insert') === 0
                || stripos($executed->sql, 'update') === 0
                || stripos($executed->sql, 'delete') === 0
               ) {
                     \DB::connection($executed->connection)->setReadPdo(null);//清空从连接,会自动使用主连接
            }
       });
}

参考资料: http://blog.sina.com.cn/s/blog_9bbafb790102win1.html

微信网页授权的两种返回结果

微信公众号网页授权的两种方式,snsapi_base、snsapi_userinfo

snsapi_base基础信息静默授权,不会打扰到用户,授权返回内容是:

{
	"id": "og11w0hu...",
	"name": null,
	"nickname": null,
	"avatar": null,
	"email": null,
	"original": {
		"access_token": "27_T...",
		"expires_in": 7200,
		"refresh_token": "EQ...",
		"openid": "og1",
		"scope": "snsapi_base"
	},
	"token": "27_TDiwj62xKsng...",
	"provider": "WeChat"
}

snsapi_userinfo用户公开信息授权,第一次需要用户确认,授权返回内容是:

{
	"id": "og11w0hu...",
	"name": "Charles",
	"nickname": "Charles",
	"avatar": "http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/PiajxSqBRaEJW4jPlAdDLJeG67fhnotIzBgL0tZjJBYnGLvG2TDPv0rAc0X7ZcZV03D4qsTicDPXTj7ibDkqbnYdw\/132",
	"email": null,
	"original": {
		"openid": "og1...",
		"nickname": "Charles",
		"sex": 1,
		"language": "zh_CN",
		"city": "扬州",
		"province": "江苏",
		"country": "中国",
		"headimgurl": "http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/PiajxSqBRaEJW4jPlAdDLJeG67fhnotIzBgL0tZjJBYnGLvG2TDPv0rAc0X7ZcZV03D4qsTicDPXTj7ibDkqbnYdw\/132",
		"privilege": []
	},
	"token": "27_CFj...",
	"provider": "WeChat"
}

本文json串使用bejson工具格式化

laravel之Eloquent之Relation 枢纽表关联关系hasManyThrough

使用laravel的eloquent写两个表的关联关系是日常操作,hasOne,hasMany,belongsTo

会遇到有枢纽表(中间表)来做多对多关系用的,hasManyThrough这个方法几个参数比较难记下来

现有三个模型User、City、UserCity,对应表users、cities、user_cities

通过UserCity枢纽表关联User和City关系

现在在User表中写上City的关联关系

class User extends Model
{
    public function cities(): Relation
    {
        $this->hasManyThrough(
            // 参数1 目标表类名
            City::class,
            // 参数2 枢纽表类名
            UserCity::class,
            // 参数3 枢纽表中和当前表关联的字段名
            'user_id',
            // 参数4 枢纽表中和目标表关联的字段名
            'city_id',
            // 参数5 当前表中和枢纽表关联的字段名,一般是主键
            'id',
            // 参数6 目标表中和枢纽表关联的字段名,一般是主键
            'id');
    }
}

prestissimo给composer加速

要求

  • composer >=1.0.0 (includes dev-master)
  • PHP >=5.3, (suggest >=5.5, because curl_share_init)
  • ext-curl

安装

$ composer global require hirak/prestissimo

卸载

$ composer global remove hirak/prestissimo

基准测试效果

288s -> 26s

$ composer create-project laravel/laravel laravel1 --no-progress --profile --prefer-dist

如何屏蔽ByteSpider今日头条(字节跳动)爬虫

字节跳动开始了搜索业务,于是派出了名叫ByteSpider的爬虫在全网开始爬取各种网站。

UserAgent其一是:

Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2404.1317 Mobile Safari/537.36; Bytespider 

第一次看到此爬虫爬取的太过分的时候,修改nginx配置,凡是遇到ByteSpider爬虫的时候,nginx返回403。配置如下

if ($http_user_agent ~* (Bytespider|webmeup)) {
    return 403;
}

过了两天,有朋友说网站很卡,看了一下nginx访问日志,发现又有爬虫来爬网站,频率非常快。

这次来的爬虫的UserAgent没有ByteSpider字样,以往常经验来看,有很大可能是字节跳动的爬虫。此爬虫的特点是,请求特别频繁;每次请求都换IP地址;IP地址在几个固定的网段;如果是普通的小爬虫,不会有这么专业的操作

升级了服务器硬件配置后,发现服务器还是卡,于是只能放大招,屏蔽爬虫的IP网段。统计一下访问日志的IP地址段,修改网络防火墙规则。笔者使用的阿里云ECS,在控制面板里面设置如下拒绝规则:

220.243.0.0/16
111.225.0.0/16 
66.249.0.0/16
110.249.0.0/16

设置好了之后,一切归于平静。能安心工作了。

接下来的一天,笔者临时解除一下防火墙拒绝规则,没有发现类似今日头条爬虫来访问

nginx访问日志按照日期分文件存储

nginx默认的access_log存储方式是单文件,小流量网站没有问题,大流量网站在经历长时间运行后,日志文件变得非常大,难以维护,查阅nginx文档后,写下配置

if ($time_iso8601 ~ '(\d{4}-\d{2}-\d{2})')
{
    set $day $1;
}
access_log /home/wwwlogs/blog.yinghualuo.cn_$day.log;

如果有更好的方案,请不吝赐教

开源协议BSD、Apache2、GPL、LGPL、MIT

BSD开源协议(original BSD licenseFreeBSD licenseOriginal BSD license

BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。

但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:

  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对 商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。

Apache Licence 2.0(Apache License, Version 2.0Apache License, Version 1.1Apache License, Version 1.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件也和BSD类似:

  1. 需要给代码的用户一份Apache Licence
  2. 如果你修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。

GPL(GNU General Public License

我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代 码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商 业软件公司开发的免费软件了。

GPL协议的主要内容是只要在一个软件中使用(”使用”指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。

由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。

其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。

LGPL(GNU Lesser General Public License

LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。

但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源 代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。

GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品。

MIT(MIT

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的。


今天又看到一个同学发布维权帖子《开源 App 被人抄袭到 iOS App Store 怎么办?》这个帖子转发到技术群的时候引发了很大的讨论,大多数同学都是声援的态度,也有较真的同学在讨论 MIT License ,那么License 是什么,MIT License 又是什么?

License就是版权许可证,里面详尽表述了你获得代码后拥有的权利,可以对别人的作品进行何种操作,何种操作又是被禁止的。软件的版权许可证可有很多方式,本文仅限于讨论开源软件协议 Open Source License。

       世界上的开源许可证(Open Source License)大概有上百种,上文提到的 MIT License 仅仅只是其中的一种而已,而我们常用的开源软件协议大致有GPLBSDMITMozillaApacheLGPL。我们不必要每个开源协议都了然于心,但是可以了解几个

主要的协议的权利和义务。

如果看完还是一头雾水的话,乌克兰程序员Paul Bagwell,画了一张分析图,说明应该怎么选择,下图为国内大牛阮一峰汉化了版本。

来一个更加清晰和完全一点的图,目前只有英文版,希望可以用同学可以汉化。

希望以上的总结可以帮助到一些同学更好的为自己的开源项目选择一个合适的开源协议,当自己的开源项目被侵权的时候不至于处于被动的位置,也希望可以帮助到大家更“合法”的应用开源项目,很多开源协议最低要求是使用者需要保留原作者对代码的声明,估计大家都忽略掉了吧。

开源不等于免费,开源也不等于没有约束。


转载自: https://blog.csdn.net/qwertyuiop_123abc/article/details/82110221

使用postman调试启用csrf验证的laravel框架方法

由于laravel框架默认开启csrf_token验证,鉴于安全性考量,不关闭csrf_token验证,post、put、patch等请求均会验证csrf_token的正确性,故写下调试教程。

当前Postman是 Version 7.9.0 win32 10.0.18362 / x64

创建一个新的postman environment

选择刚刚创建好的environment

自动获取cookie的csrf_token 到postman的全局环境里

pm.environment.set("XSRF-TOKEN",decodeURIComponent(pm.cookies.get("XSRF-TOKEN")))

在请求中,自动设置csrf_token

{{XSRF-TOKEN}}

附Postman官网地址,推荐下载App原生版本的Postman,不推荐Chrome插件版 https://www.getpostman.com/downloads/