Mysql8 版本兼容问题

先看一下查询 SELECT rownum – 1 AS ROW FROM (SELECT *, (@i :=@i + 1) AS rownum FROM xms_document, (SELECT @i := 0) AS it WHERE states=1 and catid=13 ORDER BY sortid desc,createtime desc) AS t1 WHERE id = 181

这个查询在Mysql5.7里面能正常,跑到Mysql8里面报错了。且不吐槽为啥开发这样写吧,单拆这个问题去Debug。拿到里面的子查询 SELECT *, (@i :=@i + 1) AS rownum FROM xms_document, (SELECT @i := 0) AS it WHERE states=1 and catid=13 ORDER BY sortid desc,createtime desc 发现是正常的。

最后结果发现是SELECT rownum – 1 AS ROW中ROW为Mysql关键词,最后解决加了“,修正为先看一下查询 SELECT rownum – 1 AS `ROW` FROM (SELECT *, (@i :=@i + 1) AS rownum FROM xms_document, (SELECT @i := 0) AS it WHERE states=1 and catid=13 ORDER BY sortid desc,createtime desc) AS t1 WHERE id = 181

Grafana使用技巧

1、切换图标显示在右侧【Search Option】上方。

2、时间筛选Unix时间戳用 $__unixEpochFilter(s.create_time)

3、Variables 从Mysql Query 多字段情况 使用【 SELECT field1 as __text,field2 as __value
FROM table】方式进行查询,显示的时候显示 __text,使用的时候可以使用 ${Demo:value}。

4、Row可以按变量进行Repeat。

GOGS+Drone CICD实践记录

之前一直在做Gitlab+Jenkins的CICD实践,由于这套架构太吃性能了。在小服务器上抗不住,所以构建了Gogs+Drone的CICD方案,记录下坑。

1、drone-server 1.0 版本推荐的挂载目录是 /data/drone 2.0版本推荐的挂载目录是/data

2、使用容器启动的drone,重启后再登录提示【Unauthorized】,去Gogs-用户设置-授权应用,删除之前的应用再登录即可。

3、同理,docker重启要去Gogs-项目设置里面,把之前webhook删除掉,再去drone项目把项目disable了再激活一次,解决重启后webhook的token问题。

不知道为啥drone没把webhook 和 user token 持久化下来。

iphone上mitmproxy证书设置

Mac安装mitmproxy并添加证书后,基本问题不大,都能正常运行起来

手机端iphone上下载安装mitmproxy证书:

1、手机和PC在同一个局域网中,设置wifi代理为PC端的ip,端口为mitmproxy的端口(默认8080)

2、手机浏览器访问mitm.it,下载安装mitmproxy描述文件,完成验证

3、经过上面两步,个别APP就可以访问并被mitmproxy在PC端截获,但有时发现很多APP无法上网,这时还需要添加证书的信任

“设置”——关于本机——证书信任设置——开启mitmproxy完全信任

php-fpm的进程管理模式

php-fpm的进程数可以根据设置分为动态和静态。

静态:直接开启指定数量的php-fpm进程,不再增加或者减少;
动态:开始的时候开启一定数量的php-fpm进程,当请求量变大的时候,动态的增加php-fpm进程数到上限,当空闲的时候自动释放空闲的进程数到一个下限。
这两种不同的执行方式,可以根据服务器的实际需求来进行调整。

这里先说一下涉及到这个的几个参数吧,他们分别是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。

pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件给出的说明了。

下面4个参数的意思分别为:

pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置的数量个php-fpm进程。

如果dm设置为dynamic,那么pm.max_children参数失效,后面3个参数生效。系统会在php-fpm运行开始的时候启动 pm.start_servers个php-fpm进程,然后根据系统的需求动态在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。

那么,对于我们的服务器,选择哪种执行方式比较好呢?事实上,跟Apache一样,我们运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。所以,动态方式因为会结束掉多余 的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或者VPS上使用。具体最大数量根据 内存/20M 得到。比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间。

然后对于比较大内存的服务器来说,设置为静态的话会提高效率。因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到。比如说2GB内存的服务器,可以设置为50;4GB内存可以设置为100等。

一种是pm = static,始终保持一个固定数量的子进程,这个数由pm.max_children定义,这种方式很不灵活,也通常不是默认的。

另一种是pm = dynamic,他是这样的,启动时,会产生固定数量的子进程(由pm.start_servers控制)可以理解成最小子进程数,而最大子进程数则由pm.max_children去控制,OK,这样的话,子进程数会在最大和最小数范围中变化,还没有完,闲置的子进程数还可以由另2个配置控制,分别是pm.min_spare_servers和pm.max_spare_servers,也就是闲置的子进程也可以有最小和最大的数目,而如果闲置的子进程超出了pm.max_spare_servers,则会被杀掉。

可以看到,pm = dynamic模式非常灵活,也通常是默认的选项。但是,dynamic模式为了最大化地优化服务器响应,会造成更多内存使用,因为这种模式只会杀掉超出最大闲置进程数(pm.max_spare_servers)的闲置进程,比如最大闲置进程数是30,最大进程数是50,然后网站经历了一次访问高峰,此时50个进程全部忙碌,0个闲置进程数,接着过了高峰期,可能没有一个请求,于是会有50个闲置进程,但是此时php-fpm只会杀掉20个子进程,始终剩下30个进程继续作为闲置进程来等待请求,这可能就是为什么过了高峰期后即便请求数大量减少服务器内存使用却也没有大量减少,也可能是为什么有些时候重启下服务器情况就会好很多,因为重启后,php-fpm的子进程数会变成最小闲置进程数,而不是之前的最大闲置进程数。

第三种 pm = ondemand模式,这种模式和pm = dynamic相反,把内存放在第一位,他的工作模式很简单,每个闲置进程,在持续闲置了pm.process_idle_timeout秒后就会被杀掉,有了这个模式,到了服务器低峰期内存自然会降下来,如果服务器长时间没有请求,就只会有一个php-fpm主进程,当然弊端是,遇到高峰期或者如果pm.process_idle_timeout的值太短的话,无法避免服务器频繁创建进程的问题,因此pm = dynamic和pm = ondemand谁更适合视实际情况而定。

附各参数说明:

pm string
设置进程管理器如何管理子进程。可用值:static,ondemand,dynamic。必须设置。

static – 子进程的数量是固定的(pm.max_children)。
ondemand – 进程在有需求时才产生(当请求时,与 dynamic 相反,pm.start_servers 在服务启动时即启动。
dynamic – 子进程的数量在下面配置的基础上动态设置:pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers。

pm.max_children int
pm 设置为 static 时表示创建的子进程的数量,pm 设置为 dynamic 时表示最大可创建的子进程的数量。必须设置。
该选项设置可以同时提供服务的请求数限制。类似 Apache 的 mpm_prefork 中 MaxClients 的设置和 普通PHP FastCGI中的 PHP_FCGI_CHILDREN 环境变量。

pm.start_serversin
设置启动时创建的子进程数目。仅在 pm 设置为 dynamic 时使用。默认值:min_spare_servers + (max_spare_servers – min_spare_servers) / 2。

pm.min_spare_servers int
设置空闲服务进程的最低数目。仅在 pm 设置为 dynamic 时使用。必须设置。

pm.max_spare_servers int
设置空闲服务进程的最大数目。仅在 pm 设置为 dynamic 时使用。必须设置。

pm.max_requests int
设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的。如果设置为 ‘0’ 则一直接受请求,等同于 PHP_FCGI_MAX_REQUESTS 环境变量。默认值:0。

nginx IF判断表达式

一、if语句中的判断条件(nginx)

1、正则表达式匹配:

==:等值比较;
~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写;
~*:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写;
!~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写;
!~*:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写;

继续阅读nginx IF判断表达式

Vue slot插槽继承问题

但是在实际的使用过程中,常常会出现外部组件内容需要多级嵌套传递到目标组件,那么slot可以如何实现呢?
现在假设有A,B,C三个组件,层级关系为A>B>C(父亲,儿子,孙子)

C:

<div>
    C组件
    <div>
      <slot name="pane" :data="我是C">我是c组件---外部没传递,我才显示</slot>
    </div>
</div>

B:

<div>
    B组件---这是一个中间传递的slot
    <C>
	    <div slot="pane" slot-scope="{data}">
	      <slot name="pane" :data="data"></slot>
	    </div>
    </C>
</div>

A:

<div>
    A组件
    <B>
    <div slot="pane" slot-scope="{data}">
      {{data}}注意,我要传到C了
    </div>
    </B>
</div>

转自:https://blog.csdn.net/xuxu_qkz/article/details/81115022

NC的命令使用详解

netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据。通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它。使用netcat命令所能完成的事情令人惊讶。

netcat所做的就是在两台电脑之间建立链接并返回两个数据流,在这之后所能做的事就看你的想像力了。你能建立一个服务器,传输文件,与朋友聊天,传输流媒体或者用它作为其它协议的独立客户端。

下面是一些使用netcat的例子.
继续阅读NC的命令使用详解

Nginx location规则详解

由于团队在进行前后端分离,前端接管了Nginx和node层,在日常的工作中,跟Nginx打交道的时候挺多的。之前对location的匹配规则是一知半解的,为了搞明白location是如何匹配的,查了些资料总结此文。希望能给大家带来帮助。

语法规则

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

语法规则很简单,一个location关键字,后面跟着可选的修饰符,后面是要匹配的字符,花括号中是要执行的操作。

修饰符
= 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
~ 表示该规则是使用正则定义的,区分大小写。
~* 表示该规则是使用正则定义的,不区分大小写。
^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
匹配过程
对请求的url序列化。例如,对%xx等字符进行解码,去除url中多个相连的/,解析url中的.,..等。这一步是匹配的前置工作。

location有两种表示形式,一种是使用前缀字符,一种是使用正则。如果是正则的话,前面有~或~*修饰符。

具体的匹配过程如下:

首先先检查使用前缀字符定义的location,选择最长匹配的项并记录下来。

如果找到了精确匹配的location,也就是使用了=修饰符的location,结束查找,使用它的配置。

然后按顺序查找使用正则定义的location,如果匹配则停止查找,使用它定义的配置。

如果没有匹配的正则location,则使用前面记录的最长匹配前缀字符location。

基于以上的匹配过程,我们可以得到以下两点启示:

使用正则定义的location在配置文件中出现的顺序很重要。因为找到第一个匹配的正则后,查找就停止了,后面定义的正则就是再匹配也没有机会了。
使用精确匹配可以提高查找的速度。例如经常请求/的话,可以使用=来定义location。
示例
接下来我们以一个例子来具体说明一下匹配过程。

假如我们有下面的一段配置文件:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /user/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

请求/精准匹配A,不再往下查找。

请求/index.html匹配B。首先查找匹配的前缀字符,找到最长匹配是配置B,接着又按照顺序查找匹配的正则。结果没有找到,因此使用先前标记的最长匹配,即配置B。

请求/user/index.html匹配C。首先找到最长匹配C,由于后面没有匹配的正则,所以使用最长匹配C。
请求/user/1.jpg匹配E。首先进行前缀字符的查找,找到最长匹配项C,继续进行正则查找,找到匹配项E。因此使用E。

请求/images/1.jpg匹配D。首先进行前缀字符的查找,找到最长匹配D。但是,特殊的是它使用了^~修饰符,不再进行接下来的正则的匹配查找,因此使用D。这里,如果没有前面的修饰符,其实最终的匹配是E。大家可以想一想为什么。

请求/documents/about.html匹配B。因为B表示任何以/开头的URL都匹配。在上面的配置中,只有B能满足,所以匹配B。

location @name的用法
@用来定义一个命名location。主要用于内部重定向,不能用来处理正常的请求。其用法如下:

location / {
    try_files $uri $uri/ @custom
}
location @custom {
    # ...do something
}

上例中,当尝试访问url找不到对应的文件就重定向到我们自定义的命名location(此处为custom)。

值得注意的是,命名location中不能再嵌套其它的命名location。

URL尾部的/需不需要
关于URL尾部的/有三点也需要说明一下。第一点与location配置有关,其他两点无关。

location中的字符有没有/都没有影响。也就是说/user/和/user是一样的。
如果URL结构是https://domain.com/的形式,尾部有没有/都不会造成重定向。因为浏览器在发起请求的时候,默认加上了/。虽然很多浏览器在地址栏里也不会显示/。这一点,可以访问baidu验证一下。
如果URL的结构是https://domain.com/some-dir/。尾部如果缺少/将导致重定向。因为根据约定,URL尾部的/表示目录,没有/表示文件。所以访问/some-dir/时,服务器会自动去该目录下找对应的默认文件。如果访问/some-dir的话,服务器会先去找some-dir文件,找不到的话会将some-dir当成目录,重定向到/some-dir/,去该目录下找默认文件。可以去测试一下你的网站是不是这样的。
总结
location的配置有两种形式,前缀字符和正则。查找匹配的时候,先查找前缀字符,选择最长匹配项,再查找正则。正则的优先级高于前缀字符。

正则的查找是按照在配置文件中的顺序进行的。因此正则的顺序很重要,建议越精细的放的越靠前。

使用=精准匹配可以加快查找的顺序,如果根域名经常被访问的话建议使用=。

转载自:https://segmentfault.com/a/1190000013267839