针对线上的Mysql,我们有更高级别的访问鉴权,常规等级的可以在办公网络通过VPN即可访问,而针对最高等级的鉴权,则限于更高等级的IP白名单,我们的做法是只有线上环境集群的机器才可访问。我们在线上K8S集群中创建了一个Mysql客户端的Pod,在有需要时通过该客户端访问,而它的IP是和线上环境共享的,在开放白名单内。
我们所有的操作都在终端进行,所以我们需要进行如下命令进行访问
1.切换到k8s的线上环境
2.访问指定命名空间
3.进入mysql客户端的pod
4.输入mysql命令远程登录指定机器
5.输入mysql账号密码完成登录
6.选择需要操作的DB
在如上操作了一段时间后,发现命令执行流程太长,每次需要耗费不少时间,效率非常低下。有没有可能只需要执行一条命令就完成以上操作?
最大化提高效率,快速访问指定数据库。
只需要执行一条命令即可完成以上操作,随用随取。
在搜索一番之后,发现shell的expect命令比较适合我们解决这个场景的问题,选择开发定制脚本来改善效率。以下是参考代码:
#1.切换到k8s的线上环境
kubectl config use-context $ctx
#2.访问指定命名空间
kubectl config set-context $cxt --namespace=$namespace
login(){
expect -c '
set password $password
#3.进入mysql客户端的pod
spawn kubectl exec -ti mysql-client -- env LANG=C.UTF-8 bash
expect "*oot*"
#4.输入mysql命令远程登录指定机器
send "mysql -u $user -h$host -p \r"
expect "*assword*"
#5.输入mysql账号密码完成登录
send "$password\r"
expect "*mysql*"
#6.选择需要操作的DB
send "use $db;\r"
expect "*changed*"
#7.可选择执行最常用的几条sql
send "select * from test where a = '' \\G"
interact
#expect eof
'
}
login
通过编写上面的小工具,再次访问mysql时只需执行以上shell命令即可,极大改善了访问效率。
在电商业务中,不同微服务存储的数据,有时需要核查对比,检查发现系统潜在问题。例如订单系统中存储的订单及优惠券的抵扣金额,与优惠券系统订单的抵扣金额是否匹配。访问的订单总数是否也能匹配。而我们现在常用的架构之中已经对数据库分库分表,部署在不同机器,不能连表访问。
怎么才能对不同微服务的查询结果进行快速比对呢?
输入两个不同数据库的查询结果,点击比对后,可以快速直观的获取差异数据,判断数据准确性。
通过尝试,我们发现简单的javascript就可以帮我们完成上诉需求。我们统计单天的订单,以及对应的金额进行比较。单日订单数是否匹配?订单金额是否匹配?我们以订单号拼接金额为判断单位,以下为操作界面
通过上面的小工具,我们就可以快速完成对比工作,在核对数据时派上用场。而JS的代码也并不复杂,以下提供参考:
function compare(){
//取出输入框的内容
var strA = document.getElementById("starA").value;
var strB = document.getElementById("starB").value;
//执行比较函数填充至结果框
document.getElementById("qresult").innerHTML = doCompare(strA,strB);
document.getElementById("hresult").innerHTML = doCompare(strB,strA);
}
function doCompare(strA,strB){
//换行符分割为数组
var arrA = strA.split('\n');
var arrB = strB.split('\n');
var restr = "";
//for循环逐条取出,进行对比
for(var i=0;i<arrA.length;i++){
var iss = false;
for(var t=0;t<arrB.length;t++){
if(arrA[i] != "" && arrB[t] != ""){
if(arrA[i]==arrB[t]){
iss = true;
break;
}
}
}
if(!iss){
restr += arrA[i]+" ";
}
}
return restr;
}
在mysql的使用过程中,有时需要将数据从旧库迁移到新库,除了使用mysqldump导出后再导入新库的操作外,mysql的rename操作也提供了另外一个选择。
笔者遇到的情况比较特殊。起初测试环境在我们的办公网络,mysql是对表名大小写敏感的,后来测试环境上云后改为了大小写不敏感,这时旧的一份代码是对大小写敏感的,而新的则是大小写不敏感。
最近不得不又重新启用办公网络的测试数据库,这时它对大小写敏感
的设置就让两份代码的兼容犯了难,不得不将其改为大小写不敏感
。这时新库自然是没问题的,但是已经使用过大写字母的旧表就出现了问题,必须将它全部改为小写,否则即使更改大小写敏感的属性,依然会找不到表。
这时就需要对旧表先进行处理,之后才能启用大小写不敏感的设置。处理方式就是将已存在大写字母的表统一更名为小写。
将已存在大写字母的表统一更名为小写。
使用脚本编写,执行一次即可生效。
整理操作步骤,概括如下:
1.指定需要处理的库,查询出该库下的所有表
2.针对数据表批量转小写后,导入到新库新表
#!/bin/bash
#注释1:填写数据库信息
user=test
pass=test123
host=localhost
#注释2:选择需要处理的DB
for old_db in db1 db2 db3
do
echo $old_db begin
#新库名称统一小写
new_db=$(echo $old_db | tr '[A-Z]' '[a-z]')
mysql -u$user -p$pass -h$host -e "create database if not exists $new_db;"
#查询数据库下所有表名
old_tables=$(mysql -u$user -p$pass -h$host -Nse "select table_name from information_schema.TABLES where TABLE_SCHEMA='$old_db'")
for old_table in $old_tables
do
#新表名称统一小写
new_table=$(echo $old_table | tr '[A-Z]' '[a-z]')
#统一导入新表
mysql -u$user -p$pass -h$host -e "rename table $old_db.$old_table to $new_db.$new_table"
done
echo $old_db end
done
完成以后,所有的表均为小写,这时再设置为大小写不敏感,后续即可正常使用,不再被大写困扰。
Iris是Golang中比较常用的WEB框架,我们团队在使用时引用了两个版本,后来从兄弟部门接手了一些项目,又引入了一个版本,相当于有三个版本在使用。而在go mod出来之前,我们的项目都是基于GOPATH的模式开发,长远来看肯定是需要统一Iris版本方便管理,但是项目比较多,一次性迁移完工作量大,开发机不可避免会出现同时需要兼容这三个版本的情况。如果引入错误版本,项目将运行不起来,如何同时兼容三个版本就成了问题。
同时兼容三个版本,支持快速灵活的切换。
开发指定项目时,只需执行一条命令即可选择指定版本的库进行开发。
定义3个版本,使用软链接,切换时将软链接指向不同版本的真实地址。
#V5版本
function iris_v5() {
ln -snf /Users/vince/code/go/src/github.com/geekypanda_v5 /Users/vince/code/go/src/github.com/geekypanda
ln -snf /Users/vince/code/go/src/github.com/kataras/iris_v5 /Users/vince/code/go/src/github.com/kataras/iris
}
#V12版本
function iris_v12() {
ln -snf /Users/vince/code/go/src/github.com/kataras/iris_v12 /Users/vince/code/go/src/github.com/kataras/iris
}
#V5之前的旧版本
function iris_old() {
ln -snf /Users/vince/code/go/src/github.com/geekypanda_old /Users/vince/code/go/src/github.com/geekypanda
ln -snf /Users/vince/code/go/src/github.com/kataras/iris_old /Users/vince/code/go/src/github.com/kataras/iris
}
这样在开发时,只需要针对当前项目使用的库版本,执行一条命令完成切换运行,高效便捷。
最后分享一个生活中的小例子。作为程序员每天都在和代码打交道,往大的讲,我们总说我们的代码运行在多少台终端上,有多少用户在使用我们的代码,对社会贡献很大。往小了讲,它能不能切身帮助我们处理生活中的事情呢?
深圳的几个民政局,办理婚姻登记的话要属福田和南山最难预约,因为它装修布置美观,仪式感强,受年轻人喜欢。早上放号后很快就会被抢完,但是因为临时有事取消的也不少,这就有了捡漏的空间。除了有事没事经常上去查询,怎么才能在出现预约号后快速锁定,就成了我们的诉求。
编写代码查询预约余量,减少人工查询。
解放人工查询,定时预约余量,出现预约号时钉钉提醒。
1、抓包分析响应内容。通过Charles抓包,我们可以得到民政局预约余量的响应数据。
2、编码。定时访问指定URL,指定日期有余量时发送钉钉消息。
作为后端工程师,Shell和JS平时使用不多,基本属于现学现用,它们语法并不复杂,上手简单,开发的几个工具却大大改善了日常的效率,是一个性价比极高的事情。通过上面几个例子不难发现,工具在执行流程化、大批量操作时作用明显,我们在开发过程中遇到问题或者特定场景时,通过开发小工具改善工作效率也是一个很好的选择。
Linux expect 介绍和用法一
mysql如何修改为大小写不敏感?
在 iPhone 上利用 Charles 抓包