- 博客(1539)
- 收藏
- 关注
原创 并发安全和锁
有时候在Go代码中可能会存在多个goroutine同时操作一个资源,这种情况会发生数据竞态问题。举例:var x int64var wg sync.WaitGroupfunc add() { for i := 0; i < 5000; i++ { x = x + 1 } wg.Done()}func main() { wg.Add(2) go add() go add() wg.Wait() fmt.Println(x)}上面的代码中开启了 2 个gorout
2021-03-21 13:15:16 471
原创 select多路复用
在某些场景下我们需要同时从多个通道接收数据。通道在接收数据时,如果没有数据可以接收发生阻塞。你也许会写出代码使用遍历的方式来实现:for { //尝试从ch1接收值 data,ok := <-ch1 //尝试从ch2接收值 data,ok := <-ch2}这种方式虽然可以实现从多个channel接收值的需求,但是运行性能会差很多。为了应对这种场景,Go内置了select关键字,可以同时响应多个通道的操作。select的使用类似于switch语句,它有一些列case分支和一个
2021-03-19 14:41:50 585
原创 go协程池
编写代码实现了一个计算随机数的每个位置数字之和的程序,要求使用goroutine和channel构建生产者和消费者模式,可以指定启动的goroutine数量-woker pool模式。在工作中我们通常使用workerpool模式,控制goroutine的数量,防止goroutine泄露和暴涨。一个简易的workerpool示例代码如下:package mainimport ( "fmt" "time")func worker(id int, jobs <-chan int, res
2021-03-19 14:19:23 483
原创 多协程执行收集结果
##多协程执行收集结果1、先假设有一个比较耗时的任务//假设有一个比较耗时的任务func job(index int) int { //模拟耗时,延迟500毫秒 time.Sleep(time.Millisecond * 500) return index}2、使用非协程的方式,看看需要多少时间func main() { //记录当前时间 start := time.Now() //假设这个工作需要 5 次 num := 5 for i := 0; i < num; i
2021-03-15 17:10:39 284
原创 Go在MacOS上打包成Win 及 Linux运行文件
打包命令CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.goCGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.gowin的会打包成.exe文件,win下面直接运行即可
2020-05-20 15:54:53 1761 1
原创 Context上下文包套路入门(1)
context包被称为上下文包,go 1.7加入,用于协程之间的上下文数据的传递、中止核控制超时。在网络编程中可用于请求的中止,比如服务访问链的中止:a用户注册->b调用用户服务->c调用积分服务。其中a调用b,b调用c。如果由于a和b之间因为某些原因被取消或者超时了,那么b和c之间也要取消。Context接口源码解读:type Context interface{ //返回...
2019-09-01 10:34:35 451
原创 RPC入门(2):JSONRPC使用、使用PHP调用
https://blog.csdn.net/github_26672553/article/details/100172819之前介绍的方式只适合go系统和go系统之间调用(因为它数据编码使用了go的gob编码格式)。想要其他异构系统(比如php)调用,就需要使用通用的编码格式,比如JSON。1、jsonrpc服务端代码: jsonrpc.ServeConn(client)一句就搞定...
2019-08-31 17:26:05 1711
原创 go自带的rpc包
包:net/rpc1、基于tcp且使用socket,所以必须创建socket服务端l, err := net.Listen("tcp",":8080")2、创建一个struct,基本规则如下:方法可导出(首字母大写);方法有2个参数,都是可导出类型或内建类型;方法的第二个参数是指针类型,第一个参数是接收的参数,第二个参数是返回的参数(客户端得到的值);函数有error返回typ...
2019-08-31 14:50:06 767
原创 协程通信:认识channel
有一个函数,做累加计算,如:func sum(max int) { result := 0 //从1累加到max for i := 1; i <= max; i++ { result = result + i } //最后打印结果 fmt.Println(result);}调用这个函数:func main() { sum(100); //5050}go的协...
2019-08-31 13:14:19 21730
原创 入手redis第三方库
官网:https://github.com/gomodule/redigo安装:go get github.com/gomodule/redigo/redis文档地址:https://godoc.org/github.com/gomodule/redigo/redis#pkg-examples1、简单封装redis连接客户端新建src/MyRedis.go:package src...
2019-08-31 09:43:21 666
原创 gorm:数据库连接池
连接池http://gorm.io/docs/generic_interface.html// 设置空闲连接池中的最大连接数db.DB().SetMaxIdleConns(10)// 设置到数据库的最大打开连接数db.DB().SetMaxOpenConns(100)// 设置可重用连接的最大时间量db.DB().SetConnMaxLifetime(time.Hour)改造...
2019-08-28 21:25:48 10193
原创 gorm:新增数据、封装DB初步、结合Gin实现查询API
新增数据 db, _ := gorm.Open("mysql", "root:root@/test?charset=utf8mb4&parseTime=True&loc=Local") defer db.Close() // 打开日志日志,查看执行的sql db.LogMode(true) // 新增数据 news := model.NewsModel{Title:"...
2019-08-28 14:21:24 1458
原创 gorm:结合Model进行数据映射
0、有这样一张表CREATE TABLE `news_category` ( `category_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `category_name` varchar(255) DEFAULT NULL, `category_remark` varchar(255) DEFAULT NULL, PRIMARY ...
2019-08-28 09:02:15 2252 1
原创 Gorm入手、执行原始SQL
1、安装//安装mysql驱动go get -u github.com/go-sql-driver/mysql//安装gorm库go get -u github.com/jinzhu/gorm2、连接mysqlpackage mainimport ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jinzhu/go...
2019-08-25 17:41:18 4819
原创 Gin框架速学:内置验证器的初步使用
准备1、创建model/NewsModel.go文件:package model//新闻模型定义type NewsModel struct { //新闻id Id int `json:"id"` //新闻标题 Title string `json:"title"` //新闻内容 Content string `json:"content"` //作者 Author str...
2019-08-25 11:54:34 1520
原创 Gin框架速学:创建Model、参数绑定Model的初步使用
创建Model1、创建model/bbsModel.go文件,代码如下:package modeltype bbs struct { Id int //帖子id Title string //帖子标题}//创建帖子模型func CreateBBSModel(id int, title string) bbs { return bbs{Id:id,Title:title}}...
2019-08-25 08:26:55 1579
原创 Gin框架速学:简单Dao层代码封装、使用中间件模拟"用户认证"
简单的Dao层代码封装创建dao/bbsDao.go文件,里面代码如下:package daoimport ( "github.com/gin-gonic/gin")//获取某一帖子详细func GetBBSDetail(context *gin.Context) { context.String(200, "获取id=%s的帖子", context.Param("id"))...
2019-08-24 21:59:07 1659
原创 Gin框架速学:路由分组
/v1/bbs?user=zhangsan/v1/bbs/12通过之前这个2路由地址,可以发现它们具有相同部分/v1/bbs可以分到一个路由组里,下面看gin框架如何实现: //路由分组 routerV1 := router.Group("/v1/bbs") // /v1/bbs routerV1.GET("", func(context *gin.Context) { if...
2019-08-24 18:55:34 629
原创 Gin框架速学:API的URL规则设计、带参数的路由
比如我们要这样的路由地址/v1/bbs?user=zhangsan/v1/bbs/12gin框架实现代码如下: router.GET("/v1/bbs", func(context *gin.Context) { if context.Query("user") == "" { context.String(200,"获取帖子列表") }else { context....
2019-08-24 18:41:47 1385
原创 Gin框架速学:开发环境、最简单的服务启动
官网地址:https://github.com/gin-gonic/gin准备:1、在任意路径下(不要有中文)创建api.go.com/live2、cd到api.go.com/livego mod init live.go.com#其实这里叫 go mod init xxx 都行3、然后执行:go get -u github.com/gin-gonic/gin等下载完成,用编...
2019-08-24 17:15:57 975
原创 sql解析:获取Select字段
https://blog.csdn.net/github_26672553/article/details/100048506前面已经了解这个解析sql的第三方库,继续深入学习。比如我们要获取到select查询语句中的字段id,name,ageselect id,name,age from users as t看看这个第三方库是怎么办到的?func main() { sql := ...
2019-08-24 12:24:22 1802 1
原创 sql解析:使用第三方库、获取表名称
使用第三方库https://github.com/xwb1989/sqlparser这个库基于vitessio/vitess这个数据库中间件的。安装go get -u github.com/xwb1989/sqlparser新建test.go文件:package mainimport ( "fmt" "github.com/xwb1989/sqlparser" "log"...
2019-08-24 08:23:27 1938
原创 模拟分表查询:多数据集合并
https://blog.csdn.net/github_26672553/article/details/100047058之前我们把select * from users硬生生的替换成了select * from (select * from user1 union select * from user2) as t很low,但如果你的分表需求和业务是在过于简单,也是可以的。。。func...
2019-08-23 22:55:50 613
原创 模拟分表查询:最简单的多表查询
假设我们通过手工的方式分了表user1和user2,表结构当然是一样的。我们要通过select * from users limit 100来查询。回顾一下之前的代码:https://blog.csdn.net/github_26672553/article/details/100025119sql查询主要是调用HandlerQuery函数。首先我们要明白mysql中2表联合查询是怎么写的...
2019-08-23 22:45:23 731
原创 mysql代理:创建自己的Handler处理类、支持查询数据返回
回顾https://blog.csdn.net/github_26672553/article/details/100011650在前面使用第三方库,创建了简单的msyql代理服务。我们可以:mysql -h127.0.0.1 -P4000 -uroot -p就连接上了。创建自己的Handlerconn, _ := server.NewConn(c, "root", "", server...
2019-08-22 22:31:48 227
原创 创建一个最简单的mysql代理
先介绍一个开源第三方库关于go module 环境:export GO111MODULE=onexport GOPROXY=https://goproxy.io/在go module 环境下go get -u github.com/siddontang/go-mysql注意:这不是一个纯mysql驱动,而是包含了mysql协议解析、复制(mysql replication)和类似j...
2019-08-22 11:45:30 425
原创 go的包依赖管理(1): go.mod文件、简单使用
随便cd到一个目录(英文路径)下执行:go mod init mytest 然后用编辑器打开这个目录。可以看到一个go.mod文件。然后创建core/functions.go文件,代码如下:package coreimport "fmt"func ShowName() { fmt.Println("我的名字叫张三")}可以看出在functions.go中写了一个函数。...
2019-08-21 18:37:44 836
原创 简易FailOver机制: 普通轮询算法下的计数器机制(上)
https://blog.csdn.net/github_26672553/article/details/99764970在上面实现了简单服务器健康检查机制。设置服务状态为up或down。之前说了,不能一次检查没有通过就设为down,所以需要有个计数器机制。来简单粗暴的实现一下:1、定期向url发送http请求,根据接口响应码和响应时间判断2、每个server计数器为03、如果异常,...
2019-08-20 23:05:59 248
原创 负载均衡算法:轮训算法的简单实现
所谓的轮询,就是挨个访问。//负载均衡类type LoadBalance struct{ Servers []*HttpServer //指向当前访问的服务器 CurIndex int //添加这个变量}轮询算法实现://轮询算法func (this *LoadBalance) RoundRobin() *HttpServer { server := this.Servers...
2019-08-20 21:58:15 474
原创 简易http服务健康检查:http服务定时检查、修改状态
比如我们有3个节点:9091、9092和9093。要是其中一个宕机了,就不能作为负载均衡的节点选项了。所以需要对其健康进行检查(也就是检查是否宕机了)基本机制(简易)1、定义发送http请求,并根据接口响应码和响应时间判断2、如果异常,标记为不可用。(不能一次失败就直接标记为不可用,应该有个阀值)3、异常节点恢复后,恢复节点的可用状态。具体实现1、首先保证节点启动比如我们这里给启动...
2019-08-19 21:31:32 1351
原创 负载均衡算法之加权随机算法的简单实现
1、我们在前面写过“随机算法”来实现简单的负载均衡。https://blog.csdn.net/github_26672553/article/details/99701928用过nginx配置负载均衡,可能会写过类似这样的配置:upstream lb { server xxxxxx1 weight=1 server xxxxxx2 weight=2}这表示server1和serv...
2019-08-18 15:41:13 736
原创 负载均衡算法之ip_hash简单应用
1、前面用go实现了一个超级简单的负载均衡。采用的均衡算法是“随机”。https://blog.csdn.net/github_26672553/article/details/99701928主要代码: rand.Seed(time.Now().UnixNano()) //设置随机因子,精确到纳秒 index := rand.Intn(len(this.Servers)) return...
2019-08-18 11:46:05 735
原创 随机算法 实现 负载均衡
需求:实现一个最简单的负载均衡(均衡算法采用随机算法)。具体实现:前端用户访问localhost:8080,通过反向代理随机分配到localhost:9091或lcalhost:9092。1、确保启动这2个(或多个)9091、9092web服务实现代码查看:https://blog.csdn.net/github_26672553/article/details/991650652、前...
2019-08-18 10:26:29 328
原创 设计ini配置文件格式
下载第三方库go get github.com/go-ini/ini设定一个配置文件格式:[proxy]path="/a"pass="http://localhost:9091"go读取配置文件:func main() { //加载配置文件env.ini(参照上面配置文件格式) config, err := ini.Load("env.ini") if err != nil...
2019-08-11 20:16:12 529
原创 go实现简单的很不完善的“请求-转发”(反向代理)、httpclient的初步使用
浏览器来请求我们的“反向代理”,反向代理把请求转发给真实的网站。这个中间发生了什么?下面我们用go实现一个简单的反向代理服务1、首先创建一个所谓的http服务package mainimport "net/http"type ProxyHandler struct {}func (* ProxyHandler)ServeHTTP(w http.ResponseWriter, ...
2019-08-11 09:17:08 604
原创 复习:利用go协程创建两个web服务
废话不多说,直接上代码,先创建2个协程package mainimport "net/http"func main() { // 第1个协程 go (func() { http.ListenAndServe(":9091",web1Handler{}) })() // 第2个协程 go (func() { // 第2个web服务 h...
2019-08-11 08:41:13 267
原创 httpserver学习(2):路由、设置cookie、注销、判断登录
路由管理器 ServeMuxfunc main() { myMux := http.NewServeMux() myMux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { _, _ = writer.Write([]byte("hello")) }) _ = http.ListenA...
2019-07-21 16:19:02 215
原创 httpserver学习(1):使用http包快速创建server、自定义handler
package mainimport "net/http"func main() { http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { _, _ = writer.Write([]byte("hello world")) }) http.HandleFunc("/abc"...
2019-07-21 12:53:59 399
原创 "死循环"Socket服务端、支持浏览器输出
1、把我们前面写的socket服务,改为循环监听 // 死循环中 for { // 接收客户端的消息 client, err := listener.Accept() if err != nil { fmt.Println(err) return } func(c net.Conn) { defer c.Close() // 读取客户端消息 ...
2019-06-30 09:39:54 531
原创 创建最简单的Socket服务端和客户端代码
1、服务端代码package mainimport ( "fmt" "net")func main() { // 创建监听 listener,err := net.Listen("tcp","127.0.0.1:9111") if err!=nil { fmt.Println(err) return } defer listener.Close() fmt.P...
2019-06-30 09:05:38 1089 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人