2020.10.01 去「大陈岛」看海了
大陈岛分上大陈和下大陈,下大陈开发相对完善,一般住宿都会在下大陈,下大陈比较值得去的应该就是甲午岩景区,沿着峭壁一路走到到尽头是观景台,可以面朝大海,如果晴天可以在观景台看日出。上大陈新开发了乌沙头风景区(目前是免费开放,但需要提前预约,在公众号大美大陈,我去的时候人比较少所以没要查票,当然我也没预约上),这里有乌沙滩、观景台、泡洞、滨海(绝壁)栈道,值得一去。
有一点需要注意的是,整个大陈岛的地图在各大地图软件上均不完善,很多路和景点在地图上都查不到,或者查到的是不对的。上大陈尤为明显,我骑小电驴饶了好久好久。惨~~~
行程
提前 15 天,12306 订上海 -> 台州高铁
提前 3 天,公众号大美大陈买椒江 -> 下大陈岛船票
有快船和慢船,建议慢船
建议提前备好晕船药或晕船贴
09.30 07:00 虹桥枢纽 4 路到高铁站乘车出发前往台州
11:20 到台州站,打车前往椒江七号码头
12:30 登船,驶向深蓝(东海方向)
因为海上风浪很大,所以船上是不能上甲板的,这一点和舟山群岛不太一样,舟山那边属于近海一般慢船是可以上甲板的
14:10 到达下大陈岛
...
「深入学习 Golang」之 Goroutine
进程、线程、协程进程
进程是系统资源分配的最小单位
进程包括text region,data region和stack region等
进程的创建和销毁都是系统资源级别的,因此是一种比较昂贵的操作
进程是抢占式调度,他有三个状态:等待态、就绪态、运行态
进程之间是相互隔离的,每个进程有各自的系统资源,更加安全同时也带来了进程间通信不便的问题
进程是线程的载体
线程
同一个进程的多个线程共享进程的资源
每个线程也拥有自己的一少部分独立的资源
线程相比进程更加轻量,同一个进程内的多个线程通信比多个进程间通信容易,同时也带来了同步、互斥和线程安全的问题
协程
协程调度不需要内核参与,是完全由用户态程序决定的
协程不是抢占式调度,多个协程进行协作调度,避免了系统切换开销导致 CPU 使用率高
goroutine协程并不是 Go 语言的特有机制,Go 语言是在原生语言层面支持的的协程。Go 语言可以通过通信实现 goroutine 之间的数据共享。
Golang 中,不要通过共享内存来通信,而应该通过通信来共享内存!
创建一个 goroutine 不需要太多的内存,大概 2KB 左右 ...
「Kubernetes 拾遗」之 输入 kubectl run/create/apply 之后到底发生了什么
周四的时候参加我司容器组大佬的课,问到一个问题:
kubectl run nginx --image=nginx --replicals=3 当这行命令在终端敲下回车键之后你会看到很快有三个nginx pod创建在集群的worker节点上,但当敲下回车键的时候kubernetes背后都做了什么呢?
自认为对 k8s 还算熟悉的在下一下子懵了,好像知道但又说不清楚。那今天就系统性的查资料+实践总结一下吧。
kubectl客户端验证执行客户端验证,确保非法请求(创建的资源不存在、镜像格式不正确等)的快速失败,减少对kuber-apiserver的不必要请求提升系统性能。
生成运行时对象使用generator根据需要创建资源类型来构建运行时对象(runtime object)
如果显示的设置了--generator参数,kubectl 将使用指定的生成器。如果没有指定生成器,kubectl 会根据其他参数自动选择要使用的生成器。具体优先级如下:
1234--schedule=<schedule> CronJob--restart=Always Deploy ...
「Kubernetes 拾遗」之 Probe(探针)
Kubernetes 中的健康检查是使用存活性探针和就绪性探针来实现的,基于这两种探测机制,实现了 k8s 的自愈能力。可以做到:
异常节点(pod)自动剔除,并重建
安全的滚动升级策略
存活性探针livenessProbe用于判断当前容器是否存活(running)状态,如果livenessProbe探测到容器不健康,则kubectl会杀掉该容器,并根据容器的重启策略做相应重启操作。
如果一个容器不包含livenessProbe,那么kubectl会始终认为该容器的存活性探针返回的永远是success状态。
就绪性探针readinessProbe用于判断当前容器是否完成启动(read状态),如果readinessProbe探测到容器不健康,则判定该容器不可接收流量,Endpoint Controller将从该服务对应的Service的endpoints中移除该容器的endpoint。
探测方式
HTTP
TCP
Exec 命令
实际在生产环境使用livenessProbe12345678910livenessProbe: httpGet: path: /pin ...
「深入学习 Golang」之 Channel
设计原理
不要通过共享内存的方式进行通信,而应该通过通信的方式共享内存。
在其他语言中,多个线程传递数据的方式一般是共享内存,为了解决线程的冲突就需要限制同一时间能够读写这些变量的线程数,在 go 语言中并不需要这么做,因为 Golang 提供了一种不同的并发模型,也就是通信顺序进程(Communicating sequential process, CSP)。
Golang 中的 CSP 实现Goroutine和Channel分别对应 CSP 中的实体和传递信息的媒介。Go 语言中的Goroutine可以通过Channel传递数据。
先入先出目前的 Channel 收发操作遵循了先入先出(FIFO)的设计,具体规则如下:
先从 Channel 读取数据的 Goroutine 会先接收到数据
先向 Channel 发送数据的 Goroutine 会得到先发送数据的权力
数据结构Go 语言的 Channel 在运行时使用runtime.hchan结构体表示,我们在 Go 语言创建新的 Channel 时,实际上创建的都是如下所示的结构体:
123456789101112131415 ...
Docker 基础
实现原理Namespace
namespace 是 Linux 为我们提供的用于分离进程树、网络接口、挂载点以及进程间通信等资源的方法。
Docker 通过 namespace 完成了容器与宿主机、容器与容器间的隔离。
如果机器上运行了两个容器,对宿主机而言其实这两个容器就是两个特殊的进程
Cgroups
Linux Cgroups 全程是 Linux Control Group,主要的作用就是限制进程组使用的资源上限,包括CPU、内存、磁盘、网络带宽等。
UnionFS 联合文件系统Docker 中的每一个镜像都是由一系列只读的层组成,Dockerfile 中的每一个命令都会在已有的只读层上创建一个新的层
123FROM redis:latestCOPY ./redis.conf /dataCMD redis-server /data/redis.conf
容器中的每一层都是只对当前容器进行了非常小的修改,上述的 Dockerfile 文件会构建一个拥有三层 layer 的镜像。当镜像被 docker run 命令创建时就会在最上层添加一个可写的层,也就是容器层,对以 对于运行 ...
「MySQL 拾遗」之 增删查改
就只是把很多年前学的东西捡起来看一下,虽然对于一个研发工程师来说,这些都是再基本不过的知识了,但长时间不看呢记忆总会模糊。。。
连接数据库
mysql -h [数据库地址] -u [用户名] -p
123456789101112131415# 回车后输入密码⚡ mysql -h 127.0.0.1 -u root -p rootEnter password: rootWelcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 5Server version: 5.7.22 MySQL Community Server (GPL)Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be tr ...
新 Mac 软件安装
编程
Homebrew
软件包管理工具
https://brew.sh/index_zh-cn
举栗:
1brew install git
PHPstorm
重型PHP的IDE,官网:https://www.jetbrains.com/phpstorm/
Vscode
coding, 轻量级。写前端、Golang比较舒服。
https://code.visualstudio.com/
Iterm2
终端
参考配置教程:https://learnku.com/articles/5564/mac-terminal-configuration-item2-oh-my-zsh-3024night-color-scheme
Postman
接口调试
Tableplus
DB 管理
Docker
容器相关
入门教程:https://docker_practice.gitee.io/zh-cn/introduction/
Git
代码版本管理
入门教程:https://www.liaoxuefeng.com/wiki/89 ...
2020.05.01 去「枸杞岛」养生啦
行程
提前 5 天微信公众号嵊泗客运总站购票
车船联票,上海 -> 沈家湾(车,1.5小时左右),沈家湾 -> 枸杞(船)
节假日会有加班船,但可能还是需要抢票( 07:00 开始放票)
节假日的加班船基本为快船,快船 1.5 小时到枸杞,中间不停,慢船 4 小时,中间会在嵊泗停 40 分钟左右。但是如果感觉会晕船的话最好选慢船,不然你可能会怀疑人生(PS: 别问我是怎么知道的)
我是选择错峰提前一天出行,很美好
2020.04.30 06:55 乘地铁4号线到达南浦大桥地铁站 1 号口出站,步行5分钟到上海南浦大桥客运中心
取票(自动取票机),候车,检票,出发
一路驶向东海大桥尽头,到达沈家湾码头
身份证+船票+健康码进候船室
新冠肺炎疫情防控期间,需要舟山市健康码才能进候船室(健康码需要提前申请)
登船,出发,在东海航行 4 小时到达枸杞岛干斜码头
天气好的话,在从嵊泗本岛停留之后再出发没多久就能去甲板看到海水突然变蓝的分界线,对,是突然变蓝(下面有图)
下船,换乘公交进村
三天两夜,然后返沪,路线和去的时候反方向
风景
多图预警
下面是拍的一些照片, ...
Golang 知识点梳理
new和make的区别12345678910111213141516171819202122232425262728293031323334353637package mainimport "fmt"// make 和 new 的区别// new(T) 是为一个 T 类型的变量分配内存空间并将此空间初始化为 T 的零值。返回的是新值的地址,也就是 T 类型的指针 *T,该指针指向 T 的新分配的零值。很少使用 new// make 只能用于 slice、map、channel 这三种类型。// make(T, args...) 返回的是初始化之后的 T 类型的值,这个值并不是 T 类型的零值,也不是 *T ,是经过初始化之后的 T 的引用。func main() { _new() _make()}func _new() { a := new(int) fmt.Printf("a.value.pointer:%+v\n", a) // a.value.pointer:0xc000014090 fmt.Printf(&q ...