虚拟主机/内网进行数据库管理的几个还不错的方案

背景

前面其实有文章提到,为了方便运维(更重要的原因是便宜),我的网站、服务通常是部署在虚拟主机上的。


虚拟主机一般会有配置赠送一些数据库空间,比如百度云BCH,提供了1G的免费MySQL,日常情况下也够用了,所以一般情况下,我也不需要额外再购买MySQL数据库,而是直接使用虚拟主机附赠的就成。


但是,虚拟主机赠送的数据库一般也会有较多的限制,空间、内存等各个方面,这些其实也还好,本来就没指望能性能怎么好。但是有个最大的问题是,数据库通常不提供外网访问。比如百度云,就是提供了一个PhpMyAdmin的界面方便我们进行管理。那么,如果我临时需要查看或者修改一下数据库里面的内容,就需要登录百度云->找到虚拟主机->进入对应的控制面板->找到数据库管理入口,再进去管理。更麻烦的是,页面一段时间没操作,登录就过期了,就还得再重新来一次。


这种情况可能还不止虚拟主机会遇到,有时候,一些特定网络下的机器也会有类似的限制。例如,办公网段和线上服务器网段进行了隔离,就需要用一些跳板机、代理,或者专用的数据库管理平台进行维护,Navicat这一类的数据库客户端也是无法使用的。当然,这一类情况下,我的建议是遵循规定,不要想着绕过去了。

解决登录容易过期的问题

先看百度云现在的方案,是基于PhpMyAdmin进行管理,只是这个登录验证很容易失效。如果说只是对这一点感觉麻烦,数据库的操作还是愿意基于网页版来操作的话,最简单的方案就是自己也部署一套PhpMyAdmin。


为了方便运维,也可以把PhpMyAdmin部署到一个单独的文件夹,用单独的域名来访问。这个可以参考我之前的文章《Nginx虚拟主机支持多域名部署》。


除了我们耳熟能详的PhpMyAdmin,其他也有Adminer、phpMiniAdmin、SQL Buddy等轻量级的工具,也能实现这样的效果。甚至有的工具只有1个php文件,非常适合快速部署、快速销毁。


包括PhpMyAdmin在内,我试用了下,基本都可以做到比百度云默认提供的工具更方便。

image.png

如果想用客户端呢?

页面操作,总归还是比较麻烦,不如用客户端方便。


开始,我有个思路。比如说,我在虚拟主机上部署一套代码,仿照MySQL一样,去提供基于TCP的对外接口。但是很快就排除掉了这个想法,并不是因为实现复杂,而是虚拟主机就不给你用类似listen这样的方法去监听端口,提供server的能力。甚至有的虚拟主机,连tcp client的代码都无法执行。


百度云BCH还算厚道,tcp client能执行,但是server的能力总归是不可能提供的。


于是我用类似mysql http代理之类的关键词到百度去搜,噫,意外地发现Navicat竟然默认已经提供了类似的功能。


在Navicat安装目录,可以找到类似于ntunnel_mysql.php这样的文件,将其部署到虚拟主机上,在Navicat里面就可以使用了。


创建连接的时候,有一个“HTTP”的选项卡,可以配置php部署的路径。简单配置之后就可以使用了。试了一下,效果还是不错的,操作就和默认的TCP连接差不多。


image.png


因此,如果日常使用的客户端软件就是Navicat,那么这个方案直接就能解决问题。

其他的客户端管理软件呢?

Navicat毕竟是一个收费的软件,我日常其实用的不是它,而是免费的DBeaver。DBeaver是不支持http tunnel这种方式的,甚至还可以在github的dbeaver仓库下,看到有不少人提了类似的issue(https://github.com/dbeaver/dbeaver/issues/4445),官方目前觉得不合适提供。


OK,继续想想有什么办法呢?


其实前面一开始我想到的,去在虚拟主机上部署一套代码支持mysql以TCP方式进行连接,这个方案可以再换个思路:虚拟主机上无法部署,那我是不是可以在本地启动一个server模拟mysql server,再让这个server,内部以http接口的方式去和虚拟主机上的php代码来交互?


直觉上,这个方法是可行的。而且虚拟主机上的php代码,其实我们完全可以复用Navicat的ntunnel_mysql.php代码。这样就省得我们再自己想一套交互协议了,而且php的代码也自然不用写了。这个ntunnel_mysql.php配合Navicat用得也挺好的,估计没啥大问题。


稍微看了下ntunnel_mysql.php的代码,其实也挺简单的,最核心的逻辑就是把语句执行的结果,进行拼装、打印。


我各种代码也都能写,php虽然算是我的最爱,但考虑到本地执行server的便捷性,反而第一个被排除了。比如我用swoole或者Workerman写一个tcp的server,那如果换一台电脑想执行,总归还是需要php的环境。java、python相对都好一些,可以想办法打成免依赖即可执行的文件。


结果呢,世事难预料啊!我继续在网上搜,发现了一个 https://github.com/polarrwl/hersql 工具,感觉像是随手传到了github上,按照说明(非常简略)看,可能实现的也是我想要的功能。


Go代码我是真不熟。。没办法,边试边学呗。毕竟Go代码想要提供可执行文件就可太方便了,跨平台使用也没问题。

遇到的一些问题

下载下来之后,发现编译还挺好,没啥报错就编译好了,也能跑起来。


但是,试着用DBeaver和Navicat去连接之后,发现用不了,报了错误:

no dsn specified before the query:..., you can try restarting the mysql client


看起来是在执行sql语句前,没有初始化“DSN”信息。所谓DSN,就是对数据库的一些描述,比如数据库服务器地址(host)、端口(port)、用户名、密码,甚至包括数据库名等。从代码看,这个DSN信息在执行了“USE”语句的时候(比如选择了哪个数据库)会自动执行。


可是DBeaver、Navicat,到底在连接数据库的时候,执行哪些语句,这个我们无法控制。我猜测,可能这个代码针对以前的Navicat版本是可以使用的?不过,这个不重要,重要的是现在遇到这个问题要怎么解决。


这个工具提供的样例配置里面,只有ntunnel_mysql的访问地址,而没有提供用户名、密码等配置信息,不太清楚是不是以前的Navicat配置时,这些信息会转化成初始化的DSN配置传进来。那么如果现在没有的话,我干脆就把这个放到配置文件里面直接指定吧。于是,我就在配置里面加上了这些默认信息。如果DSN连接没有初始化,那就用配置里面的数据库信息,先初始化一次。


再继续用,发现针对一些数据量比较小的数据表没问题了,但是访问一些数据量稍微大一点的,就有新的错误:

Reader.parseBlockValueWithFirstByte read value n:[1] != [19]


这个错误是在hersql通过http请求获得了response之后,解析的过程中报出来的。既然ntunnel_mysql.php,在Navicat里面直接用http连接的方式用得好好的,那我自然还是宁可相信,它返回的内容本身没问题,还是hersql自己解析时候有bug。


于是又系统地学习了一下go语言里面http请求、reader之类的知识,把response打印出来一点点定位。

经过艰苦地定位,并没有找到原因,但是。。。莫名其妙地好了-____-!!!(猜测可能和拼接的http request,或者是这些response的byte转换、解析有关,但既然好了。。就也不想再继续折腾了)

最终方案

因此,经过一番定位、修复,这个工具重新可用了。


我也把一些代码进行了重构后,放回了github(https://github.com/poisonbian/hersql),也发布了一个release,方便大家可以直接下载可执行文件来使用。


欢迎大家试用并Star!


本文链接:https://www.poisonbian.com/post/5045.html 转载需授权!

分享到:
原文链接:,转发请注明来源!
「虚拟主机/内网进行数据库管理的几个还不错的方案」评论列表

发表评论