Category Archives: Coding

Windows 10下国内网络安装 minikube

Minikube 代理 Windows 10下环境下安装

最近在学习k8s,按照官方文档安装,遇到一些网络相关的问题,在这里记录下。

安装步骤参考这个链接, 坑在网络这一块,在国内网络环境下安装比较困难。

方案1

使用阿里云编译的支持Docker Mirror版本的,链接在这里

方案2

使用自己的梯子,以hyperv为例,SS开启了允许来自LAN的连接,Proxy的bypass关掉,可能需要打开防火墙端口。

  • 以管理员身份打开CMD
  • 启动minikube,这里虚拟机里面的docker要pull镜像,给docker-env设置代理 minikube start --vm-driver hyperv --hyperv-virtual-switch="minikube" --docker-env HTTP_PROXY=http://192.168.2.105:1080 --docker-env HTTPS_PROXY=http://192.168.2.105:1080,这个命令就可以。
  • 部署好之后,找到minikube的IP,把minikube ip%userprofile%\.minikube\machines\minikube\config.json里面Env一段,加上"NO_PROXY=localhost,192.0.0.0/24"

顺利的话,输出是下面这样的。

PS C:\WINDOWS\system32> minikube start  --vm-driver hyperv --hyperv-virtual-switch="minikube" --docker-env HTTP_PROXY=http://192.168.2.105:1080 --docker-env HTTPS_PROXY=http://192.168.2.105:1080
o   minikube v0.34.1 on windows (amd64)
>   Creating hyperv VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
-   "minikube" IP address is 192.168.2.116
-   Configuring Docker as the container runtime ...
- env HTTP_PROXY=http://192.168.2.105:1080
- env HTTPS_PROXY=http://192.168.2.105:1080
-   Preparing Kubernetes environment ...
-   Pulling images required by Kubernetes v1.13.3 ...
-   Launching Kubernetes v1.13.3 using kubeadm ...
-   Configuring cluster permissions ...
-   Verifying component health .....
+   kubectl is now configured to use "minikube"
=   Done! Thank you for using minikube!

遇到的问题

  • 安装成功了,但是访问网络有503错误

minikube ssh进去看到一个docker镜像没有启动起来,docker logs containerID查看错误(最终没有解决),删掉%userprofile%\.minikube整个目录,minikube delete然后重新用上面的start 脚本启用

  • 安装过程遇到问题

启用过程加--v=7把verbose级别调到debug,看输出的log

  • 虚拟机内部pull mirror报错

这个是proxy设置错了,可以先minikube stop,修改%userprofile%\.minikube\machines\minikube\config.json里面的配置,然后重新start

  • stop卡住,从hyperv manager进去,账号root,不需要密码,然后shutdown now

  • 提示TLS handshake timeout, 把NOPROXY配置加上

  • 其他

多(重)喝(启)热(试)水(试)

Hangfire 实践

Hangfire实践

Hangfire是一个执行background job的组件,支持.Net Framework和.Net Core。 在一些中小型的项目中,如果没有专门做background job的服务的话,使用Hangfire是一个不错的选择。因为其可以直接host在WebSite中,直接跟着网站发布即可。

配置

配置是非常方便的,参考官方文档即可, 基于OWIN的都可以。

存储方面,Hangfire支持MSSQL, Redis, Mongo等。 我们使用的Redis的,由于Redis需要Pro版本, 可以第三方开源版本,比如这个,基于StackExchange.Redis实现的,支持的.Net版本不是很全,由于代码并不复杂,不支持的版本自己编译下就好。 安装的时候会引入很多新的组件,使用的时候要留意与现有组件版本冲突。

任务类型

Hangfire可以处理多种类型的Job。

  • 即时任务
  • 延时任务
  • 循环任务

Pro版本支持批量的执行的一些特性。

即时任务,就是个消息队列,支持Queue的优先级,比如某个Queue优先级较高且里面有数据,则会优先把这个Queue里面的处理完成。

延时任务,就是个定时任务,本质上和上面的没什么区别,不过Hangfire把他们分开处理了,从Redis里面的数据可以看到他们的数据结构不同。

Continuations,这个功能可以多做些事情,比如失败了做一些额外的事情。

任务配置

Hangfire里面的任务都为Action类型,直接Enqueue时说明调用什么方法即可。 对于Generic接口的方法调用, 配置下就可以支持从IoC里面读取配置。如果IoC没有,且要用带参数的构造函数就比较惨,在ASP.NET Core里面,手动注册其实现方法。 IServiceCollection.AddTransient,应该是这个。

其他

  • 有个基础功能的Dashboard,如果要开启远程登陆,要配置Authentication
  • 支持Job的失败重试
  • 记得看Deployment to PROD那一段的说明!

调试ASP.NET Core 源代码

今天在Stackoverflow上面看到一个Routing相关的问题, 看起来和想的不一样, 于是想调试下代码看看里面的细节, 结果发现非常方便,所以分享下。

我最开始的想法是从Github上面下载源码,然后Attach to Process.

先关掉Just My Code这个开关。PS: 没需要不要关这个开关,会让调试变慢。

于是开始动手,本地dotnet new webapidotnet build xx.sln, dotnet xx.dll

从github下载源码,https://github.com/aspnet/Mvc.git,打开后切换至对应版本的release分支。

后面就直接attach 到 dotnet.exe

此时断点是不亮的,如提示,没有加载运行所需的PDB文件: 'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.1.3\Microsoft.AspNetCore.dll'. Cannot find or open the PDB file., 我们可以去巨硬的symbol server下载, 在Visual Studio中,Debug->Windows->Modules,找到要调试的DLL, 右键Load Symbols即可。

这样就断点亮起来,就可以继续调试了。

后面发现更方便的办法就是直接在Module里面Load symbols,如果本地没有源码,VS会提示是否要下载源码,不过如果要完整调试的话,需要下载好多次的感觉,还是把代码仓库搬下来省事。

DotNet Framework 源码阅读记录

Dotnet Core最近发布了2.1版本,相信也更加趋于稳定了。 虽然我接触.NET是从3.5+开始,不过这次可以从1.0开始见证它的发展了。 最近闲的时候阅读了一部分源码,虽然之前也看过不少,不过没有记录。 现在有了博客,就记录一点。

主要看的是下面几个仓库里面的内容:

Void 是个结构体(Struct)

Public struct Void{}

AggregateException

AggregateException 是伴随着async/await引入的新的类型, 有个Flatten方法, 可以将内部异常展开(貌似是BFS算法). 在调用时,将内部异常保存在一个ReadOnlyCollection中,不可改变. –> See how stack trace generated

DBNull

DbNull.Value is an instance of DbNull type. ToString() => string.Empty
Inheriated from Iconvertible, all other convertation will throw exception. InvalidCastException

DateTime

使用大量的缓存
* Days per 100 years/400years
* 里面存储了dates to 1601/1899/1970/10000,因为对应了不同的纪元 -> https://en.wikipedia.org/wiki/Epoch_(reference_date)
* Ticks per ms/s/Minute/Hour/Day
* s_daysToMonth365/s_daysToMonth366

字典

Dictionay – hash with chaining
HashTable – hash using open addressing

Overflow检测

在数字一部分, 有一段很精妙的overflow检测方式, 在做算法题的时候会用到。

        public static int Abs(int value)
        {
            if (value < 0)
            {
                value = -value;
                if (value < 0)
                {
                    ThrowAbsOverflow();
                }
            }
            return value;
        }

以及几个有意思的常量, 对于自己设计框架有帮助。

        public const double NegativeInfinity = (double)-1.0 / (double)(0.0);
        public const double PositiveInfinity = (double)1.0 / (double)(0.0);
        public const double NaN = (double)0.0 / (double)0.0;

Span

Span<T> https://msdn.microsoft.com/en-us/magazine/mt814808.aspx

DebuggerTypeProxy

在设计框架里面的类型时, 可以使用DebuggerTypeProxy在debugger里面显示的内容。

命令行语法说明怎么读

在阅读Git帮助文档时,经常会看到长长的语法说明,看起来有点晕,于是查询了这类怎么读。

$ man man

有一部分内容可以参考:
The following conventions apply to the SYNOPSIS section and can be used as a guide in other sections.

bold text type exactly as shown.
italic text replace with appropriate argument.
[-abc] any or all arguments within [ ] are optional.
-a|-b options delimited by | cannot be used together.
argument … argument is repeatable.
[expression] … entire expression within [ ] is repeatable.

另外Git book里面的参数是<>扩起来的。