后端开发童鞋们, 自己开发机用的是Windows系统电脑(台式机或笔记本), 而开发的程序和使用的数据库等要运行在Linux服务器上, 这种情况有木有? 提前声明: 本文并不讨论操作系统的比较, 以及用Windows电脑开发后端程序是否合适的问题. 如果你现在用的是macOS系统或者Linux系统电脑, 或者你开发的程序及使用的工具不需要在Linux系统上运行. 那么请略过本文, 以免浪费时间.
说明: 如果对细节不关注的童鞋, 请直接跳到最后看小结与展望
0x00 背景说明
我现在做的项目是用.NET Core+MySQL+Nginx技术栈, 而这个服务器端程序最终也要运行在Linux系统上.
最初, 使用VS2017+Windows版MySQL+IIS服务器在我的笔记本电脑(以下简称开发机)开发调试, 功能开发好以后, 发布程序到Linux系统上, 服务器要安装.NET Core运行时, Linux版MySQL数据库和Nginx Web服务器.
后来遇到两个问题, 都是因Linux系统上的名称(一个是文件名, 另一个是MySQL数据库表名)区分大小写, 而Windows系统不区分, 导致程序出Bug.
主要原因是自己对Linux系统不熟悉(我是个假的程序员吗?), 但是换个角度想, 如果调试时的环境与真实服务器环境一致, 还是可以减少诸如此类的麻烦. 下面请看我所知道的解决方案, 如果有更好的欢迎补充!
0x01 几种方案
- 方案一: 特点优雅, 换用MacBook Pro笔记本, 因为macOS也是类UNIX操作系统, 所以原生支持Linux命令及资源. 还有一个最大的好处是, 现在越来越多的软件也支持这个平台, 比如我的公司要求使用Evernote来共享文档, 老板和员工的沟通工具使用QQ和微信, 等等. 这些需求不是我们个人能决定的, 因此一个平台有这些软件的客户端是非常有必要的.
- 方案二: 特点真实, 普通PC安装Linux系统, 什么发行版无所谓, 当然最好能跟生产服务器上的发行版一致. 可以说在这种情况下开发机调试的结果跟生产服务器运行的结果几乎一致, 但是不方便的地方就是缺少必要软件支持, 比如上面提到的, 有人可能会说了用Wine, 或者在Linux系统中安装虚拟机, 或者用它们的Web版, 这些方法我都试过, 跟在macOS或Windows操作系统上使用客户端, 完全是两个感受, 真的你要是能接受各种折腾和不方便, 那我也没话说. 举个例子一年多以前我在浏览器中用Evernote的Web版, 居然不能添加表格和在表格中插入行!
- 方案三: 特点卡顿, 开发机上的操作系统无所谓, 然后安装虚拟机, Windows专有的HyperV, 免费的Virtual Box, VM Ware, macOS系统上专有的一款虚拟机, 等等. 如果开发机很强悍, 比如16核处理器+64G内存+2TB固态硬盘等等, 那么这个方案的"卡顿"特点就消失得无影无踪, 随之带来的就是方便, 想开几个操作系统就开几个, 觉得系统里有些乱, 重新装一个就好, 但是我的开发机仅仅4核+8G内存, 而且散热也一般, 还要保证物理真机上也要运行一些程序, 不知道你们的跟我的情况一样不.
- 方案四: 特点新颖, 使用Docker技术, Docker技术其实在今天看来已经不是最新的技术了. 但是我仍然只是看了一些入门讲解, 并没有实践经验. 因此本方案我不做详细评论, 只简单提一句. 尤其生产服务器也在使用Docker技术, 那么就更方便了. 直接把发布的程序和相关资源打包到Docker容器中, 无论是在开发机, 还是生产服务器, 用的都是同一个Docker容器, 管它什么操作系统, 运行环境肯定完全一致.
- 方案五: 特点如一, 这个方案分为初级版和高级版. 初级版是用远程桌面, 高级版是用TeamViewer等使用VPN专线技术的软件. 好处不用说了, 你一直都在同一台电脑上工作, 其他地点的电脑只是用了外设及网络. 远程桌面我用过一段时间, 比起在当前电脑上使用的体验来看, 还是有些许不如. 至于TeamViewer软件我没用过, 但是它的使用方式我了解过, 在某些条件下还是很实用的.
- 方案六: 这个方案特点就不说了, 因为是我这次要介绍的方案. 前提还是使用Windows操作系统, 使用的工具小名叫WSL, 大名叫Windows Subsystem on Linux之前是beta版, 在1709版Win10以后就是正式版, 提前强调一下, 这个系统还不完善, 仍然有bug, 跟直接用Linux发行版相比, 还是有些许不如. 不过现在这个版本已经比beta版要强很多, 已经能到可以使用的程度了, 而且这一版的Ubuntu是16.04呦. 这个系统的原理我就不介绍了, 从使用上来看, 跟在macOS上用Linux命令和各种资源工具类似. 所以以前选择在Windows系统中安装虚拟机方案的童鞋, 并且开发机性能不高的, 强烈建议你们要尝试一下.
0x02 WSL的安装使用
- WSL的安装
- 所有设置 -> 应用 -> 相关设置: 程序和功能(也可以直接控制面板 -> 程序 -> 程序和功能) -> 启用或关闭Windows功能 -> 适用于Linux的Windows子系统, 勾选上它, 然后确定, 需要重启电脑;
- Microsoft Store中搜索"Ubuntu", 会有2个搜索建议, 一个是"在Windows下运行Linux", 另一个就是"Ubuntu", 当然你也可以搜索"openSUSE", 或者其他的发行版名称, 以后支持的发行版会越来越多, 然后选择你需要的那个发行版, 点击获取安装, 如果一个发行版都不安装, 在命令行中输入"bash", 会提示当前不存在Linux子系统(大概这个意思), 安装之后可以直接在开始菜单中点击Ubuntu这个UWP程序, 这是一个包装过的命令行窗口, 并且直接启动到Linux子系统中, 也可以先启动cmd命令行窗口或者PowerShell窗口, 输入
bash
命令, 也会启动Linux子系统
- WSL的使用
- 第一次进入Linux子系统会提示你创建一个用户, 输入用户名和密码, 再次确认密码即可;
- 我安装的是Ubuntu16.04版本, 目标是安装MySQL数据库服务器版并运行. 再次强调: 这不是虚拟机*3(重要的事情说三遍), 因此Windows系统使用的资源跟Linux子系统是一套, 所以要注意端口占用的问题. 比如我之前安装过Windows版MySQL数据库, 并监听3306端口, 那么最好在Linux子系统中运行时, 先停掉Win系统中的MySQL数据库服务. 我是直接把Win版MySQL数据库删了, 重新安装了一个仅Client的程序, 然后服务器安装在Linux子系统中;
- 我在Linux子系统中试了几个我自己知道的工具和命令, 有Python3和Git, 文本编辑器有vim和nano, 还有
ifconfig
和ping
这2个命令也可用, 查看当前系统信息的命令:lsb_release -a
, 还有ssh
好像也能用(不太会用, 以后学, 另外以后Windows系统可能原生支持openSSH, 上面的方案中也漏掉了这种用Windows操作系统电脑远程SSH登录服务器的方式); - Linux子系统有一点要注意, 那就是Windows主系统中的文件能够在Linux子系统中可见, 而Linux子系统中的文件在Windows主系统中不可见. 举个栗子, 比如我在Windows主系统的
C:DemoProjectsrc
目录中的源代码文件, 可以对其使用dotnet publish
或git pull / push
(前提是安装Win版的DotNet Core和Git), 然后我在Linux子系统中就可以在/mnt/c/Demo/Project/src
这个路径下找到这些文件, 并且也可以执行同样的命令(前提是安装Linux版的DotNet Core和Git). 也就是只要在相应的系统中安装了对应的程序包, 就可以执行对应的操作或命令, 只不过需要你能访问到命令执行的对象文件, 但是你在Linux子系统的/home/Demo/Project/src
目录下存放的源代码文件, 在Windows主系统中访问不到, 这就没办法了. 因此我一般都是把开发工作放在Windows系统中, 而把部署运行工作放在Linux子系统下. - 这里多说一句, 这个Linux子系统不支持GUI图形界面, 你可以把它当成Linux服务器版来用. 但是有Linux大神已经给出解决方案, 在Linux子系统中安装GIMP程序, 然后在Windows10系统中安装Xming软件(注意这是Win版软件), 我个人觉得没必要, 有需要的童鞋请自行百度, 网上教程很多;
0x03 MySQL数据库的安装和刨坑
- 更新apt更新源:
sudo apt-get update
; - 安装MySQL服务器版:
sudo apt-get install mysql-server
, 我没连VPN, 但是下载速度还行; - 安装完毕后, 需要输入MySQL数据库root用户的密码, 这个密码一定要记着! 我的同事小伙伴, 安装完Win版的MySQL数据库以后, 当时输入的root用户密码是啥就没记, 然后一直连着公司服务器的测试数据库. 结果有一天想把测试库down到本机, 结果发现本机MySQL数据库服务器进不去...;
- 从这里开始就是刨坑, 对面那个童鞋你别笑, 你也可能遇到这个坑, 对, 就说你呢! 第一个坑就是, 我兴冲冲地输入:
mysql -u root -p
, 没有熟悉的MySQL命令交互界面, 取而代之的给我报了个错, 如下:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
. MySQL的本地访问是用socket的, 关键的问题是我的/var/run/
目录下根本没有mysqld
目录, 这是什么鬼? 移除后重装也不行, 网上有5个解决方案: 传送门, 我也逐一地尝试了, 用管理员身份运行PowerShell, 在其中运行bash, 然后运行mysql命令前加sudo, 这样就排除的权限的问题, 但是还不行; 执行sudo service mysql status
, 可以看到服务器状态已停止, 执行sudo service mysql start
命令启动服务器, 启动失败; 什么连接数太大, 权限不足, 服务没启动等都不能解决; 甚至说mysql.cnf或my.cnf文件中指向的mysql.sock文件路径不对, 需要更改, 就更不可能了. 首先我就没找到mysql.sock这个文件, 我指哪个路径呢? 其次我的mysql.cnf或my.cnf文件中内容也不对, 没有更改socket文件指向的节点. 但是服务肯定是没启动起来, 后来也不知道到了哪个目录下, 运行sudo service mysql start
就成功了. 我在写这篇文章时, 特意找了一下那个目录, 没找到也记不清楚了, 大家根据自己的实际情况刨坑吧(可以先试试在/etc/init.d/
目录下执行); - 用Windows版MySQL客户端程序也能连接这个MySQL数据库服务器了, 但是运行程序又报错, 说是连接数据库失败, 调试了一下发现程序中用的IP地址, 而我在客户端程序里用的localhost, 客户端里用ip也不能访问, 在Linux子系统中首先执行ifconfig命令, 发现有本机ip地址, 再执行ping命令, 也能ping通, 最后执行
sudo mysql -h [ip地址] -P 3306 -u root -p
, 提示无法连接. 这个网上有很多人说, 其实本来不用写出来, 大家自行百度或Google就行. 但是我发现一个坑, 就是网上的说法一般都是在原生Linux发行版系统下, 位置为/etc/my.cnf
,/etc/mysql/my.cnf
,/usr/local/etc/my.cnf
或其他, 而我是在/etc/mysql/mysql.conf.d/
目录下找到了mysqld.cnf这个文件, 把其中的bind-address设置项注释掉即可, 不知道为什么存放的文件不一样; - 最后试了一下, 表名真的区分大小写了. 另外用户如果想用ip访问, 那么MySQL数据库用户的From Host要设置成%, 这个别忘记了. 还有一个尚未解决的问题, 就是至少要有一个bash窗口开启, 如果所有的都关闭, Windows系统会认为你从Linux子系统中退出, 这样也是访问不到MySQL数据库服务的, 网上有人说先做个vbs脚本, 启动一个隐藏窗口的bash, 并且把这个脚本添加到开机启动中执行, 另外Linux子系统第一次启动时也需要一个sh脚本自动开启MySQL数据库服务, 但是我没实践, 这个大家请自便, 唯一注意的就是启动MySQL数据库服务后至少保留一个bash程序的窗口.
0x04 小结和展望
- 目的是Windows系统上运行MySQL客户端, Windows系统中的Linux子系统运行MySQL服务器端;
- 在"启用或关闭Windows功能"里勾选"适用于Linux的Windows子系统", 确定并重启;
- 在Microsoft Store里下载并安装Ubuntu或其他的Linux子系统的UWP程序, 并运行, 首先输入用户名及密码;
- 在Linux子系统中安装MySQL数据库服务器端, 安装成功后输入root用户的密码, 并启动数据库服务;
- 我在安装好MySQL后遇到两个问题, 一个是执行
mysql -u root -p
时报错, 这个要在特定的目录下重新启动服务; 另一个是无法用ip访问, 这个是找到对应的配置文件, 把bing-address = 127.0.0.1
设置行注释掉即可; - 以后计划在Linux子系统中安装Nginx服务器, 然后把.NET Core程序部署到Nginx服务器上运行;
- 最后如果你对这方面有什么使用心得, 欢迎补充!