探究vscode debug流程,解决无法运行go程序的问题

问题描述 vscode 无法以 run 模式运行 go 项目(只能以 debug 模式调试),并且有如下报错。 图中被遮盖的部分是项目内的 package,并非第三方 package,也就是说在以 run 模式运行 go 项目时无法找到其他的 go 文件,只能找到入口文件。 初步排查 找不到其他文件,首先想到的是 GO_PATH 的问题,但是项目使用了 go mod,允许在 GO_PATH 之外的路径创建项目,所以这个怀疑点排除。接下来怀疑 vscode 的配置有问题,每个 vscode 项目中都有 .launch.json 文件,配置运行代码时的环境,下面是项目中的 .launch.json。 { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Launch", "type": "go", "request": "launch", "mode": "auto", "program": "${workspaceRoot}/src/main.go", "env": {}, "args": [] } ] } 可以看到 .launch.json 里没有指定程序的工作目录,debug 模式和 run 模式会不会默认的工作路径不同呢?于是在 main 函数里使用 os.Getwd() 打印一下当前的路径,结果如下: ...

四月 20, 2020 · 2 分钟 · Zhiya

viper从etcd读取配置失败的问题

问题描述 Viper (本文环境是 Viper 1.1.0)是 Go 应用程序的完整配置解决方案,在很多项目中都有应用。etcd是一个分布式 KV 存储,最直接的应用是配置中心。 Viper 除了支持从文件中读取配置,还支持从远程的配置中心读取配置,使用下面的代码进行配置。 viper.AddRemoteProvider("etcd", "http://127.0.0.1:2379", "conf.toml") viper.SetConfigType("toml") err := viper.ReadRemoteConfig() if err != nil { panic(err) } 运行后报错panic: Remote Configurations Error: No Files Found,检查后发现 etcd 开启了 tls,所以需要用 https 协议访问 etcd 的 API,更新代码如下。 viper.AddSecureRemoteProvider("etcd", "https://127.0.0.1:2379", "conf.toml", "key_path") viper.SetConfigType("toml") err := viper.ReadRemoteConfig() if err != nil { panic(err) } 使用AddSecureRemoteProvider方法替换AddRemoteProvider方法,问题依旧。 定位问题 跟踪源码发现,最终像 etcd 发送请求的是go-etcd包(目前 go-etcd 已经不维护),在 go-etcd 的 requests.go 文件中找到了相关的源码,go-etcd 调用了 net/http 包向 etcd 发送请求。 这个时候忽然想到 etcd 的证书是自签名的,访问自签名证书的 https 接口应该会报错啊,怎么会请求到内容呢?如下图,在 Chrome 中访问 etcd 的自签名 https 接口,会提示证书无效。 ...

四月 16, 2020 · 1 分钟 · Zhiya

使用Pipfile代替reqirements.txt

很多语言都提供了环境隔离的支持,例如nodejs的node_module,golang的go mod,python也有virtualenv和pyvenv等机制。为了建立依赖快照,通常会用pip freeze > requirements.txt 命令生成一个requirements.txt文件,在一些场景下这种方式就可以满足需求,但是在复杂场景下requirements.txt就力不从心了。 requirements.txt appdirs==1.4.3 astroid==2.3.3 attrs==19.3.0 black==19.3b0 certifi==2019.11.28 chardet==3.0.4 click==7.1.1 et-xmlfile==1.0.1 Flask==1.1.1 gevent==1.4.0 greenlet==0.4.15 idna==2.9 isort==4.3.21 itsdangerous==1.1.0 jdcal==1.4.1 Jinja2==2.11.1 lazy-object-proxy==1.4.3 MarkupSafe==1.1.1 mccabe==0.6.1 numpy==1.18.2 openpyxl==3.0.3 pandas==1.0.3 pylint==2.4.4 python-dateutil==2.8.1 pytz==2019.3 requests==2.23.0 six==1.14.0 tinydb==3.15.2 toml==0.10.0 typed-ast==1.4.1 urllib3==1.25.8 Werkzeug==1.0.0 wrapt==1.11.2 requirements.txt文件中只记录了依赖的版本,所以如果遇到官方的pypi源下载速度慢,需要使用更快的国内镜像下载,通常只能使用pip install -i安装或者修改全局的pip.conf文件。 当某个项目使用确定的python版本,这个版本也并不能在requirements.txt中体现,只能通过readme或者文档来记录,并且需要在创建虚拟环境时手动调用正确的python版本。 项目需要使用flake8、pylint、black等代码优化工具时,这些依赖也会被pip freeze命令写入requirements.txt中,然而这些依赖是不需要出现在生产环境的。 Pipfile Pipenv的出现,一举解决了上面的问题,Pipenv是Kenneth Reitz在2017年1月发布的Python依赖管理工具,他所基于的Pipfile则用来替代requirements.txt。 [[source]] name = "pypi" url = "https://pypi.doubanio.com/simple" verify_ssl = false [dev-packages] isort = "*" black = "==19.3b0" pylint = "*" [packages] flask = "*" tinydb = "*" pandas = "*" requests = "*" gevent = "*" openpyxl = "*" [requires] python_version = "3.6" 好处1:记录内容更详细 相比于requirements.txt,Pipfile多了pip源的设置,可以针对不同项目使用不同环境。并且将依赖分为dev和默认环境,例如pylint、flake8、black等依赖,可以将他们放入dev依赖中。 ...

三月 31, 2020 · 1 分钟 · Zhiya

Docker COPY 复制文件夹的诡异行为

问题现象 在制作 docker 镜像时,有复制某一个路径下所有文件和文件夹到镜像的需求,写下了如下 dockerfile: FROM alpine WORKDIR /root/test_docker_proj COPY * ./ 原始目录结构是这样的: /projects/test_docker_proj ├── Dockerfile ├── dir1 │ ├── dir11 │ │ └── file11 │ └── file1 └── file2 然而复制到 docker 镜像里的目录结构变成了这样: /root/test_docker_proj ├── Dockerfile ├── dir11 │ └── file11 ├── file1 └── file2 可以看到 dir1 这个文件夹并没有被复制到镜像里,但是 dir1 中的子文件夹和文件都被复制进来了,和 dir1 同级的文件也被复制了。也就是说,在 COPY 执行的过程中,第一层文件夹被「解包」了。 COPY/ADD 行为逻辑 为了确定 COPY 和相似的 ADD 命令的行为,做了以下测试: FROM alpine WORKDIR /root/test_docker_proj_1 COPY * ./ WORKDIR /root/test_docker_proj_2 ADD * ./ WORKDIR /root/test_docker_proj_3 COPY ./ ./ WORKDIR /root/test_docker_proj_4 ADD ./ ./ WORKDIR /root/test_docker_proj_5 COPY ./dir* ./ WORKDIR /root/test_docker_proj_6 ADD ./dir* ./ 通过测试可以发现 COPY/ADD 命令有这么几个规则: ...

十月 28, 2019 · 1 分钟 · Zhiya

探究 Pandas 读取 Excel 文件报错问题

问题描述 使用 Pandas 的 read_excel 方法读取一个 16 万行的 Excel 文件报 AssertionError 错误: "/Users/XXX/excel_test/venv/lib/python3.7/site-packages/xlrd/xlsx.py", line 637, in do_row assert 0 <= self.rowx < X12_MAX_ROWS AssertionError 背后原理 Excel 文件有两种默认格式,在 Excel 2007 以前,使用扩展名为 .xls 格式的文件,这种文件格式是一种特定的二进制格式,最多支持 65,536 行(在 Excel 97 之前支持的最大行数是 16,384),256 列表格。从 Excel 2007 版开始,默认采用了基于 XML 的新的文件格式 .xlsx,支持的表格行数达到了 1,048,576,列数达到了 16,384。需要注意的是,将 .xlsx 格式的文件转换为 .xls 格式的文件时,65,536 行和 256 列之后的数据都会被丢弃。 版本 最大行数 最大列数 文件格式 Excel 97 之前 16,384 256 .xls Excel 97 到 Excel 2003 65,536 256 .xls Excel 2007 及以后版本 1,048,576 16,384 .xlsx Pandas 读取 Excel 文件的引擎是 xlrd,xlrd 在读取 Excel 文件时,xlrd/xlsx.py 文件的 637 行会对行号做断言,判断行号是否在 0 - 1,048,576(Excel支持的最大行数) 的范围内。这段代码是这样的: ...

八月 22, 2019 · 2 分钟 · Zhiya