前言

公司最近来了个任务,要求统一导入入口,入口作导入文件读取和切片作用,并兼容全部产品线。

大致设计思路:
Excel -> FTP-> 系统定时任务扫描 -> 读取导入Excel -> 独立写入本地SQLite -> 数据切片 -> 切片MQ派发 -> MQ消费读取SQLite切片数据 -> 调用业务函数 -> 获取处理结果 -> 扫描切片数据处理状态 -> 合并导入数据和状态变更

其中要求数据切片处理和MQ消费的服务器不为同一台服务器,并存在资源抢夺情况。部署环境是Win Server。

至于会有小伙伴问为什么要SQLite,Server库不香吗?
问就是要求!不接受其他提案!

在我本地实施时,我通过文件共享的方式映射磁盘驱动,在开发的过程很顺利,但在快完成的时候,与我一起做这个功能的大哥出现了 unable to open database file。
而在我完成自己的相关功能,部署在测试服时,另一台服务器的MQ消费定时任务一直报 unable to open database file。

情况

设文件服务器,消费端
消费端为MQ定时任务,通过Win服务挂载运行

Data Source=Z:sqllite.db;Version=3;
消费端通过映射网络驱动器路径访问sqlite文件库报错
Data Source=192.168.1.1sqllite.db;Version=3;
即使通过UNC访问依然报错

unable to open database file。

发现问题

在我本机跑程序均正常,但另一位大哥和程序挂载到Win服务上就不行。

为了确认是不是文件问题,我用大哥的电脑使用程序检查Path路径也不存在,对于程序来说,是不存在这样的路径的,所以不是文件问题

共享的文件夹也给了EveryOne角色

在翻阅很多资料后,发现映射网络驱动器分用户一说。
比如我们平常用的自己的Win账号用户和管理员权限开启程序用户并不是一个用户,映射网络驱动器对他们来说是分开的

在一些情况下,使用管理员权限开启的程序,是无法找到你直接在‘此电脑’创建的映射网络驱动器,因为这是用一般用户创建的映射网络驱动器

解决管理员映射网络驱动器问题

其实知道原因,这个答案很明显,我们直接用管理员权限创建映射网络驱动器就能使用管理员来访问
使用管理员权限打开终端,使用命令创建映射
net use z: 192.168.1.1SQLiteDb

另外也可以通过修改注册表文件
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem
添加 EnableLinkedConnections DWORD 值为 1

这就解决了大哥的问题,可上面的解决方案也无法解决挂载到Win服务的程序

求助大佬

在翻阅很多文章无果后,找了公司最厉害的大佬帮忙看看什么情况后解决:

其实问题是挂载在Win服务的角色,也是单独的一个用户,而他没有权限访问网络位置

最后大佬得出的方案是:
**
1.共享文件夹 EveryOne、NetWork权限
2.消费端使用管理员登陆系统并互通共享,在链接时使用目标服务器管理员账号登陆
**

尝试大佬方案

大佬给出解决方案后,猛然发现之前自己连接都是用Guest账号登陆的
得到解决方式后,着手自己尝试了一下。
但!是!
网络驱动器
依然! 无!法!使!用!

那行,我换UNC吧?
依然! 无!法!使!用!

然后又去国外翻了下资料,发现SQLite是为了文件安全(并发处理可能对文件有损坏风险,但我这个方案写操作不会并发,就不需要考虑这个问题),是关闭了网络链接的。
而在C#的System.Data.Sqlite可以开启这个网络链接的设置
public SQLiteConnection(string connectionString, bool parseViaFramework)
在 New SQLiteConnection时,parseViaFramework给True就行

解决

最后,我使用UNC,开启SQLite网络链接
终于可以使内网多台服务器访问SQLite,实现分布式消费导入功能。
可喜可贺,又学到了新东西
image.png

Q.E.D.


随意游世