每日新闻

每日新闻

GoCN每日新闻资讯
有问必答

有问必答

Go相关的问题,技术相关的问题
文章分享

文章分享

技术文章分享,让知识传播给更多的人
招聘应聘

招聘应聘

为Gopher服务的招聘应聘平台

百度GOPROXY代理服务

dolfly 发表了文章 • 0 个评论 • 181 次浏览 • 2 天前 • 来自相关话题

百度GOPROXY代理服务https://goproxy.baidu.com/ ...查看全部

百度GOPROXY代理服务


https://goproxy.baidu.com/

gout v0.0.4发布,新增接口benchmark功能

guonaihong 发表了文章 • 0 个评论 • 198 次浏览 • 3 天前 • 来自相关话题

gout简介gout 是go开发的流式http client。v0.0.4版本主要功能是benchmark功能拥有此版本gout,助你很方便开发出apache ab此类轮子。benchmark功能性能如何 ...查看全部

gout简介

gout 是go开发的流式http client。v0.0.4版本主要功能是benchmark功能

拥有此版本gout,助你很方便开发出apache ab此类轮子。

benchmark功能性能如何


Changlog:

  • #95 优化文档
  • #97 修改New接口
  • #98 优化文档2
  • #103 quick start增加综合示例
  • #107 BindHeader函数tag设置没生效(fix)
  • #109 修改debug模式默认配色方案
  • #92 benckmark模式
  • #105 优化超时API
  • #102 提升测试覆盖度

项目地址

github地址https://github.com/guonaihong/gout


httplib.Post请求触发

spf 回复了问题 • 2 人关注 • 2 个回复 • 101 次浏览 • 2019-12-05 17:01 • 来自相关话题

基于Go语言的论坛系统 bbs-go 3.0.4 发布,欢迎各位大神围观指导~

fuckshit 发表了文章 • 0 个评论 • 313 次浏览 • 2019-11-18 12:56 • 来自相关话题

更新内容优化文章列表加载性能,将加载方式修改为上拉加载更多,这种方式在加载列表时不需要count列表总数量,当数据量大时count很耗时。修改网站样式和配色 ...查看全部

更新内容

  • 优化文章列表加载性能,将加载方式修改为上拉加载更多,这种方式在加载列表时不需要count列表总数量,当数据量大时count很耗时。
  • 修改网站样式和配色,新的样式和配色更加好看。
  • 重构前端页面组件,将公用部分抽象成可复用组件。
  • 重构代码完全遵循eslint配置的规则,让eslint没有警告⚠️。
  • 新增配置项站外链接跳转,开启后站外链接需要用户确认后才能进行跳转。

文档地址

公众号

欢迎关注公众号码农俱乐部获取更多干货资源。

码农俱乐部

交流QQ群

bbs-go-qq.jpg

功能预览

前台页面.png
后台页面.png

课程

bbs-go搭建课程上线啦,快来跟着我一步步搭建属于你的bbs吧。该课程会带领大家一步步的了解并熟悉Go语言开发,如果你是一个Go语言初学者,或者正准备学习Go语言,那么这个课程非常适合你。如果你熟练掌握了本课程中的知识点,相信你就已经入门Go语言开发,并能胜任日常的开发工作了。

Go 是非常年轻的一门语言,它的主要目标是兼具Python等动态语言的开发速度和 C/C++ 等编译型语言的性能与安全性。Go 语言发布以来更是受到中国开发者的青睐,头条、七牛、360、腾讯、阿里等大厂的重要服务都开始使用Go语言构建,国内的Go语言研发岗位的薪水也是很可观的。

gochat - 纯go实现的im即时通讯系统(支持水平扩展)

gochat 发表了文章 • 0 个评论 • 545 次浏览 • 2019-11-04 15:56 • 来自相关话题

项目推荐- 项目地址:https://github.com/LockG ...查看全部

项目推荐
- 项目地址:
https://github.com/LockGit/gochat

- 类别:Go

- 项目描述:

gochat为纯go实现的即时通讯系统,支持私信消息与房间广播消息,各层之间通过rpc通讯,支持水平扩展。
使用redis作为消息存储与投递的载体,相对kafka操作起来更加方便快捷,所以十分轻量。
各层之间基于etcd服务发现,在扩容部署时将会方便很多。
由于go的交叉编译特性,编译后可以快速在各个平台上运行,gochat架构及目录结构清晰,
并且本项目还贴心的提供了docker一键构建所有环境依赖,安装起来十分便捷。

- 推荐理由:
轻量快捷不臃肿,水平可扩展,docker快速构建所有环境,迅速体验im即时通讯,
各层架构清晰,文档说明详细。

系统架构:



服务发现:


消息投递


聊天室预览:

gout 新版本发布,golang实现的http 流式客户端

guonaihong 发表了文章 • 0 个评论 • 361 次浏览 • 2019-10-28 09:09 • 来自相关话题

地址 ...查看全部

地址

    gout github地址

简介

    gout是go写的流式客户端,为提高编码效率而开发。特性丰富,使用方便。

技能树




yiigo 4.x 版本发布

IIInsomnia 发表了文章 • 0 个评论 • 380 次浏览 • 2019-10-25 11:50 • 来自相关话题

# yiigo[![golang](https://img.shields.io/badge/Language-Go-green.svg?style=flat)](https://golang.org)[![GitHub rele ...查看全部

# yiigo

[![golang](https://img.shields.io/badge/Language-Go-green.svg?style=flat)](https://golang.org)
[![GitHub release](https://img.shields.io/github/release/IIInsomnia/yiigo.svg)](https://github.com/iiinsomnia/yiigo/releases/latest)
[![GoDoc](https://godoc.org/github.com/iiinsomnia/yiigo?status.svg)](https://godoc.org/github.com/iiinsomnia/yiigo)
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)

The best and the most wanted package for junior gophers, probably.

## Features

- Support [MySQL](https://github.com/go-sql-driver/mysql)
- Support [PostgreSQL](https://github.com/lib/pq)
- Support [MongoDB](https://github.com/mongodb/mongo-go-driver)
- Support [Redis](https://github.com/gomodule/redigo)
- Support [Zipkin](https://github.com/openzipkin/zipkin-go)
- Support [Apollo](https://github.com/philchia/agollo)
- Use [gomail](https://github.com/go-gomail/gomail) for email sending
- Use [toml](https://github.com/pelletier/go-toml) for configuration
- Use [sqlx](https://github.com/jmoiron/sqlx) for SQL executing
- Use [gorm](https://gorm.io/) for ORM operating
- Use [zap](https://github.com/uber-go/zap) for logging

## Requirements

`Go1.11+`

## Installation

```sh
go get github.com/iiinsomnia/yiigo/v4
```

## Usage

#### Config

- `yiigo.toml`

```toml
[app]
env = "dev" # dev | beta | prod
debug = true

[apollo]
app_id = "test"
cluster = "default"
address = "127.0.0.1:8080"
cache_dir = "./"

[apollo.namespace]
# 自定义配置对应的namespace

[db]

[db.default]
driver = "mysql"
dsn = "username:password@tcp(localhost:3306)/dbname?timeout=10s&charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&loc=Local"
# dsn = "host=localhost port=5432 user=root password=secret dbname=test connect_timeout=10 sslmode=disable" # pgsql
max_open_conns = 20
max_idle_conns = 10
conn_max_lifetime = 60 # 秒

[mongo]

[mongo.default]
dsn = "mongodb://username:password@localhost:27017"
connect_timeout = 10 # 秒
pool_size = 10
max_conn_idle_time = 60 # 秒
mode = "primary" # primary | primary_preferred | secondary | secondary_preferred | nearest

[redis]

[redis.default]
address = "127.0.0.1:6379"
password = ""
database = 0
connect_timeout = 10 # 秒
read_timeout = 10 # 秒
write_timeout = 10 # 秒
pool_size = 10
pool_limit = 20
idle_timeout = 60 # 秒
wait_timeout = 10 # 秒
prefill_parallelism = 0

[log]

[log.default]
path = "app.log"
max_size = 500
max_age = 0
max_backups = 0
compress = true

[email]
host = "smtp.exmail.qq.com"
port = 25
username = ""
password = ""
```

- config usage

```go
yiigo.Env("app.env").String()
yiigo.Env("app.debug").Bool()
```

#### Apollo

```go
type QiniuConfig struct {
*yiigo.DefaultApolloConfig
BucketName string `toml:"bucket_name"`
}

var qiniu = &QiniuConfig{DefaultApolloConfig: yiigo.NewDefaultConfig("qiniu", "qiniu")}

if err := yiigo.StartApollo(qiniu); err != nil {
log.Fatal(err)
}
```

#### MySQL

```go
// default db
yiigo.DB().Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
yiigo.Orm().First(&User{}, 1)

// other db
yiigo.DB("foo").Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
yiigo.Orm("foo").First(&User{}, 1)
```

#### MongoDB

```go
// default mongodb
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

defer cancel()

yiigo.Mongo().Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})

// other mongodb
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)

defer cancel()

yiigo.Mongo("foo").Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
```

#### Redis

```go
// default redis
conn, err := yiigo.Redis().Get()

if err != nil {
log.Fatal(err)
}

defer yiigo.Redis().Put(conn)

conn.Do("SET", "test_key", "hello world")

// other redis
conn, err := yiigo.Redis("foo").Get()

if err != nil {
log.Fatal(err)
}

defer yiigo.Redis("foo").Put(conn)

conn.Do("SET", "test_key", "hello world")
```

#### Zipkin

```go
reporter := yiigo.NewZipkinHTTPReporter("http://localhost:9411/api/v2/spans")

// sampler
sampler := zipkin.NewModuloSampler(1)
// endpoint
endpoint, _ := zipkin.NewEndpoint("yiigo-zipkin", "localhost")

tracer, err := yiigo.NewZipkinTracer(reporter,
zipkin.WithLocalEndpoint(endpoint),
zipkin.WithSharedSpans(false),
zipkin.WithSampler(sampler),
)

if err != nil {
log.Fatal(err)
}

client, err := tracer.HTTPClient(yiigo.WithZipkinClientOptions(zipkinHttp.ClientTrace(true)))

if err != nil {
log.Fatal(err)
}

b, err := client.Get(context.Background(), "url...",
yiigo.WithRequestHeader("Content-Type", "application/json; charset=utf-8"),
yiigo.WithRequestTimeout(5*time.Second),
)

if err != nil {
log.Fatal(err)
}

fmt.Println(string(b))
```

#### Logger

```go
// default logger
yiigo.Logger().Info("hello world")

// other logger
yiigo.Logger("foo").Info("hello world")
```

## Documentation

- [API Reference](https://godoc.org/github.com/iiinsomnia/yiigo)
- [TOML](https://github.com/toml-lang/toml)
- [Example](https://github.com/iiinsomnia/yiigo-example)

**Enjoy

[开源] gev (支持 websocket 啦): Go 实现基于 Reactor 模式的非阻塞网络库

惜朝 发表了文章 • 0 个评论 • 389 次浏览 • 2019-10-24 11:04 • 来自相关话题

https://github.com/Allenxuxu/gev[gev](https://github.com/Allenxuxu/gev) ...查看全部

https://github.com/Allenxuxu/gev

[gev](https://github.com/Allenxuxu/gev) 是一个轻量、快速、高性能的基于 Reactor 模式的非阻塞网络库,底层并不使用 golang net 库,而是使用 epoll 和 kqueue。

现在它支持 WebSocket 啦!

支持定时任务,延时任务!

⬇️⬇️⬇️

## 特点

- 基于 epoll 和 kqueue 实现的高性能事件循环
- 支持多核多线程
- 动态扩容 Ring Buffer 实现的读写缓冲区
- 异步读写
- SO_REUSEPORT 端口重用支持
- 支持 WebSocket
- 支持定时任务,延时任务

## 性能测试

> 测试环境 Ubuntu18.04
- gev
- gnet
- eviop
- evio
- net (标准库)

### 吞吐量测试




仓库地址: https://github.com/Allenxuxu/gev

是否可以增加一个用 go 编写的开源(国产,或者全部)项目列表呢

DennisMao 回复了问题 • 3 人关注 • 3 个回复 • 304 次浏览 • 2019-10-18 10:52 • 来自相关话题

分享一个 go 的开源项目 - Jenkins 命令行客户端 jcli

回复

linuxsuren 发起了问题 • 1 人关注 • 0 个回复 • 184 次浏览 • 2019-10-16 10:03 • 来自相关话题

Go语言实现字节记录锁

PoormaJin 发表了文章 • 0 个评论 • 218 次浏览 • 2019-10-09 09:48 • 来自相关话题

1、实现文件锁2、实现字节记录锁仓库地址:https://gi ...查看全部

1、实现文件锁

2、实现字节记录锁

仓库地址:https://github.com/jinjiangcc/flock

使用实例:https://github.com/jinjiangcc/flock/blob/master/examples/main.go

BookStack v2.1 发布,功能类似 GitBook 和看云的在线文档管理系统

皇虫 发表了文章 • 2 个评论 • 277 次浏览 • 2019-09-24 12:26 • 来自相关话题

## 程序介绍BookStack,分享知识,共享智慧!知识,因分享,传承久远!BookStack 是基于 Mindoc、使用Go语言的Beego框架开发的功能类似GitBook和看云的在线文档管理系统,实现 ...查看全部


## 程序介绍

BookStack,分享知识,共享智慧!知识,因分享,传承久远!

BookStack 是基于 Mindoc、使用Go语言的Beego框架开发的功能类似GitBook和看云的在线文档管理系统,实现了文档采集、导入、电子书生成以及版本控制等强大的文档功能,并推出了配套的开源微信小程序 [BookChat](https://gitee.com/truthhun/BookChat)。

## 升级日志

- [x] 解决 2.0 版本,初始化管理员失败(密码长度修改导致)的问题
- [x] html转json实现,以兼容各种小程序和uni-app的富文本组件`rich-text`对内容的渲染
- [x] markdown导入功能获取标题优化
- [x] 内容采集持续优化,URL链接替换优化
- [x] 支持隐藏收录入口
- [x] 支持隐藏项目开源入口
- [x] API接口用户注册接口,支持控制每小时和每天的用户注册数量,以避免恶意攻击
- [x] 文档内容,SEO 标题支持获取文档的上一个文档的标题
- [x] `puppeteer`采集优化
- [x] 首页分类,增大块点击范围以优化体验
- [x] 编译的时候版本变量注入
- [x] 管理后台用户列表用户注册时间格式化
- [x] 增加虚拟根目录



## 程序升级

本次升级,数据库表结构有新增和调整,不管还是升级或是新部署时,务必先执行如下命令升级数据库表
```
./BookStack install
```

默认管理员账号密码调整为:
```
admin
admin888
```

详细 [安装部署文档](https://www.bookstack.cn/read/help/Ubuntu.md)

## 相关地址

**BookStack 官网**
- 书栈网:https://www.bookstack.cn

**BookStack 开源地址**
- Gitee(码云)开源: https://gitee.com/truthhun/BookStack
- GitHub 开源: https://github.com/TruthHun/BookStack

**BookStack 配套微信小程序 BookChat 开源地址**
- Gitee(码云)开源:https://gitee.com/truthhun/BookChat
- GitHub 开源:https://github.com/truthhun/BookChat

**BookStack 配套手机APP BookChatApp 开源地址**
- Gitee(码云)开源:https://gitee.com/truthhun/BookChatApp
- GitHub 开源:https://github.com/truthhun/BookChatApp

## 配套微信小程序 BookChat 小程序码

![BookChat](https://images.gitee.com/uploads/images/2019/0812/213324_d6225213_1593004.png "BookChat")

根据Golang定义的接口生成proto文件

Akka 发表了文章 • 0 个评论 • 309 次浏览 • 2019-09-21 08:45 • 来自相关话题

# go2proto **不用了解Protobuf语法也能轻松使用golang开发GRPC服务** go2proto 可以很轻松的根据Golang定义的接口生成proto文件,很大程度简化GRPC服务的开发工 ...查看全部
# go2proto

**不用了解Protobuf语法也能轻松使用golang开发GRPC服务**

go2proto 可以很轻松的根据Golang定义的接口生成proto文件,很大程度简化GRPC服务的开发工作。当公司要使用GRPC开发项目的时候就不用再感叹`学不动了`

## show code

- 创建一个user.go, 写入如下内容

```go
package server

type User interface {
Createuser(request Request) Response
}

type Request struct {
Name string
}
type Response struct {
Result string
}
```

- 生成proto文件

在user.go 同目录下执行 ` go2proto -f user.go` 就会自动在当前目录的proto文件夹生成user.proto 文件

```protobuf
// Code generated by go2proto. DO NOT EDIT.
syntax = "proto3";
package proto;

service User {
rpc Createuser (Request) returns (Response) {}
}

message Request {
string Name = 1;
}

message Response {
string Result = 1;
}
```

是不是很简单呢,可以完全不用了解Protobuf语法,只要用Go定义接口就可以

## 安装

```shell
go get -u github.com/akkagao/go2proto
```

## 使用

安装完执行 go2proto 如果能输出一下内容则说明安装成功

```shell
➜ go2proto git:(master) ✗ go2proto
go2proto version: go2proto/1.0.0
Usage: go2proto [-f] [-t]

Options:
-f string
source file path
-t string
proto file target path (default "proto")
```

-f 参数用于指定 go接口文件

-t 参数用于指定生成的proto文件存储的目录

## 注意事项

由于这里定义服务的go文件只是用于生成proto文件,建议不要在代码中引用这里定义的struct。

切记由于proto中的字段顺序都是有编号的,所以不要轻易删除字段或修改字段顺序。尤其是项目发布后。

重要的事情说三遍:

**不要删除字段,不要修改顺序**

**不要删除字段,不要修改顺序**

**不要删除字段,不要修改顺序**

## 实现方法

使用Go提供的源码解析工具把go文件解析成ast语法树,然后分析ast语法树内容。通过模板生成proto文件。

代码很简单关键代码不到300行,有兴趣可以花几分钟时间看一下。

## 参考资料:

https://www.jianshu.com/p/937d649039ec

https://segmentfault.com/a/1190000020386857

感谢以上两篇博客的作者

gnet: 一个轻量级且高性能的 Go 网络库

panjf2000 发表了文章 • 1 个评论 • 625 次浏览 • 2019-09-18 16:08 • 来自相关话题


gnet












# 博客原文
https://taohuawu.club/go-event-loop-networking-library-gnet

# Github 主页
https://github.com/panjf2000/gnet

欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦。

# 简介

`gnet` 是一个基于 Event-Loop 事件驱动的高性能和轻量级网络库。这个库直接使用 [epoll](https://en.wikipedia.org/wiki/Epoll) 和 [kqueue](https://en.wikipedia.org/wiki/Kqueue) 系统调用而非标准 Golang 网络包:[net](https://golang.org/pkg/net/) 来构建网络应用,它的工作原理类似两个开源的网络库:[libuv](https://github.com/libuv/libuv) 和 [libevent](https://github.com/libevent/libevent)。

这个项目存在的价值是提供一个在网络包处理方面能和 [Redis](http://redis.io)、[Haproxy](http://www.haproxy.org) 这两个项目具有相近性能的Go 语言网络服务器框架。

`gnet` 的亮点在于它是一个高性能、轻量级、非阻塞的纯 Go 实现的传输层(TCP/UDP/Unix-Socket)网络库,开发者可以使用 `gnet` 来实现自己的应用层网络协议,从而构建出自己的应用层网络应用:比如在 `gnet` 上实现 HTTP 协议就可以创建出一个 HTTP 服务器 或者 Web 开发框架,实现 Redis 协议就可以创建出自己的 Redis 服务器等等。

**`gnet` 衍生自另一个项目:`evio`,但是性能更好。**

# 功能

- [高性能](#性能测试) 的基于多线程模型的 Event-Loop 事件驱动
- 内置 Round-Robin 轮询负载均衡算法
- 简洁的 APIs
- 基于 Ring-Buffer 的高效内存利用
- 支持多种网络协议:TCP、UDP、Unix Sockets
- 支持两种事件驱动机制:Linux 里的 epoll 以及 FreeBSD 里的 kqueue
- 支持异步写操作
- 允许多个网络监听地址绑定在一个 Event-Loop 上
- 灵活的事件定时器
- SO_REUSEPORT 端口重用

# 核心设计

## 多线程模型

`gnet` 重新设计开发了一个新内置的多线程模型:『主从 Reactor 多线程』,这也是 `netty` 默认的线程模型,下面是这个模型的原理图:


multi_reactor



它的运行流程如下面的时序图:


reactor



现在我正在 `gnet` 里开发一个新的多线程模型:『带线程/go程池的主从 Reactors 多线程』,并且很快就能完成,这个模型的架构图如下所示:


multi_reactor_thread_pool



它的运行流程如下面的时序图:


multi-reactors



## 通信机制

`gnet` 的『主从 Reactors 多线程』模型是基于 Golang 里的 Goroutines的,一个 Reactor 挂载在一个 Goroutine 上,所以在 `gnet` 的这个网络模型里主 Reactor/Goroutine 与从 Reactors/Goroutines 有海量通信的需求,因此 `gnet` 里必须要有一个能在 Goroutines 之间进行高效率的通信的机制,我没有选择 Golang 里的主流方案:基于 Channel 的 CSP 模型,而是选择了性能更好、基于 Ring-Buffer 的 Disruptor 方案。

所以我最终选择了 [go-disruptor](https://github.com/smartystreets-prototypes/go-disruptor):高性能消息分发队列 LMAX Disruptor 的 Golang 实现。

## 自动扩容的 Ring-Buffer

`gnet` 利用 Ring-Buffer 来缓存 TCP 流数据以及管理内存使用。







# 开始使用

## 安装

```sh
$ go get -u github.com/panjf2000/gnet
```

## 使用示例

```go
// ======================== Echo Server implemented with gnet ===========================

package main

import (
"flag"
"fmt"
"log"
"strings"

"github.com/panjf2000/gnet"
"github.com/panjf2000/gnet/ringbuffer"
)

func main() {
var port int
var loops int
var udp bool
var trace bool
var reuseport bool

flag.IntVar(&port, "port", 5000, "server port")
flag.BoolVar(&udp, "udp", false, "listen on udp")
flag.BoolVar(&reuseport, "reuseport", false, "reuseport (SO_REUSEPORT)")
flag.BoolVar(&trace, "trace", false, "print packets to console")
flag.IntVar(&loops, "loops", 0, "num loops")
flag.Parse()

var events gnet.Events
events.NumLoops = loops
events.OnInitComplete = func(srv gnet.Server) (action gnet.Action) {
log.Printf("echo server started on port %d (loops: %d)", port, srv.NumLoops)
if reuseport {
log.Printf("reuseport")
}
return
}
events.React = func(c gnet.Conn, inBuf *ringbuffer.RingBuffer) (out []byte, action gnet.Action) {
top, tail := inBuf.PreReadAll()
out = append(top, tail...)
inBuf.Reset()

if trace {
log.Printf("%s", strings.TrimSpace(string(top)+string(tail)))
}
return
}
scheme := "tcp"
if udp {
scheme = "udp"
}
log.Fatal(gnet.Serve(events, fmt.Sprintf("%s://:%d", scheme, port)))
}

```

## I/O 事件

`gnet` 目前支持的 I/O 事件如下:

- `OnInitComplete` 当 server 初始化完成之后调用。
- `OnOpened` 当连接被打开的时候调用。
- `OnClosed` 当连接被关闭的时候调用。
- `OnDetached` 当主动摘除连接的时候的调用。
- `React` 当 server 端接收到从 client 端发送来的数据的时候调用。(你的核心业务代码一般是写在这个方法里)
- `Tick` 服务器启动的时候会调用一次,之后就以给定的时间间隔定时调用一次,是一个定时器方法。
- `PreWrite` 预先写数据方法,在 server 端写数据回 client 端之前调用。

# 性能测试

## Linux (epoll)

### 系统参数

```powershell
Go Version: go1.12.9 linux/amd64
OS: Ubuntu 18.04
CPU: 8 Virtual CPUs
Memory: 16.0 GiB
```

### Echo Server

![echolinux.png](https://img.hacpai.com/file/2019/09/echolinux-fca6e6e5.png)


### HTTP Server

![httplinux.png](https://img.hacpai.com/file/2019/09/httplinux-663a0318.png)


## FreeBSD (kqueue)

### 系统参数

```powershell
Go Version: go version go1.12.9 darwin/amd64
OS: macOS Mojave 10.14.6
CPU: 4 CPUs
Memory: 8.0 GiB
```

### Echo Server

![echomac.png](https://img.hacpai.com/file/2019/09/echomac-7a29e0d1.png)


### HTTP Server

![httpmac.png](https://img.hacpai.com/file/2019/09/httpmac-cb6d26ea.png)


# 证书

`gnet` 的源码允许用户在遵循 MIT [开源证书](https://github.com/panjf2000/gnet/blob/master/LICENSE) 规则的前提下使用。

# 待做事项

> gnet 还在持续开发的过程中,所以这个仓库的代码和文档会一直持续更新,如果你对 gnet 感兴趣的话,欢迎给这个开源库贡献你的代码~~

beego 代码自动生成器

猴子 发表了文章 • 0 个评论 • 388 次浏览 • 2019-09-17 18:12 • 来自相关话题

平时我们用 Beego 开发小项目的时候,经常会遇到一个这样的问题,就是同样的业务 ,代码我们要重复写好多次,改的只是一个小小的地方。即使是复制也会显得很繁琐。所以我不自量力搞了个工具帮助我们快速实现增删查改操作。下面来介绍一下这个小工具。 ...查看全部
平时我们用 Beego 开发小项目的时候,经常会遇到一个这样的问题,就是同样的业务 ,代码我们要重复写好多次,改的只是一个小小的地方。即使是复制也会显得很繁琐。所以我不自量力搞了个工具帮助我们快速实现增删查改操作。下面来介绍一下这个小工具。

## Gii beego 自动化代码生成

#### 1.介绍
Gii 是一个为了协助快速开发 beego 项目而创建的项目,通过 Gii 您可以很容易地为你已存在的数据表在你指定的目录创建 Model 以及 Controller 。它基于 beego 为你写好created ,update,put,已经 delete 等操作方法。
> 注意不能完全依靠 Gii 为你生成的东西,你需要检查一下再进行使用。

#### 2.安装

您可以通过如下的方式安装 bee 工具:

```
go get github.com/1920853199/go-gii
```
#### 3.使用
```
package main

import (
"github.com/1920853199/go-gii"
)

func main() {

source := "xxxx:xxxxxxxx@tcp(127.0.0.1)/abc"
gii.Column(source,"article","")

//beego.Run()
}
```

参数介绍
1. 第一个参数 source :数据库连接信息
2. 第二个参数 name 数据表名称
3. 第三个参数 controllerPath 是指定 Controller 生成的路径

> 直接执行这个文件后会在 beego 项目的目录的 models下生成对应数据表的 model,在 controller 下的指定路径生成控制器

结果:

![](http://117.50.7.147:8888/static/uploads/2019091715571981.png)

Controller ```article.go```代码

```
package home

import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/validation"
)

type ArticleController struct {
beego.Controller
}

func (c *ArticleController) List() {


limit, _ := beego.AppConfig.Int64("limit") // 一页的数量
page, _ := c.GetInt64("page", 1) // 页数
offset := (page - 1) * limit // 偏移量

o := orm.NewOrm()
obj := new(models.Article)

var data []*models.Article
qs := o.QueryTable(obj)

// 获取数据
_, err := qs.OrderBy("-id").Limit(limit).Offset(offset).All(&data)
if err != nil {
c.Abort("404")
}


/*c.Data["json"]= &data
c.ServeJSON()
c.StopRun()*/


// 统计
count, err := qs.Count()
if err != nil {
c.Abort("404")
}

c.Data["Data"] = &data
c.Data["Count"] = count
c.Data["Limit"] = limit
c.Data["Page"] = page
}

func (c *ArticleController) Put() {
id, err := c.GetInt("id", 0)

if id == 0 {
c.Abort("404")
}

// 基础数据
o := orm.NewOrm()
obj := new(models.Article)
var data []*models.Article
qs := o.QueryTable(obj)
err = qs.Filter("id", id).One(&data)
if err != nil {
c.Abort("404")
}
c.Data["Data"] = data[0]

}

func (c *ArticleController) Update() {

id, _ := c.GetInt("id", 0)


/*c.Data["json"] = c.Input()
c.ServeJSON()
c.StopRun()*/

response := make(map[string]interface{})

o := orm.NewOrm()

obj := models.Article{Id: id}
if o.Read(&obj) == nil {
// 需要补充修改的信息
// 如 :obj.Reply = reply

valid := validation.Validation{}

// 补充需要验证的信息
// 如:valid.Required(message.Reply, "Reply")

if valid.HasErrors() {
// 如果有错误信息,证明验证没通过
// 打印错误信息
for _, err := range valid.Errors {
//log.Println(err.Key, err.Message)
response["msg"] = "新增失败!"
response["code"] = 500
response["err"] = err.Key + " " + err.Message
c.Data["json"] = response
c.ServeJSON()
c.StopRun()
}
}

if _, err := o.Update(&obj); err == nil {
response["msg"] = "修改成功!"
response["code"] = 200
response["id"] = id
} else {
response["msg"] = "修改失败!"
response["code"] = 500
response["err"] = err.Error()
}
} else {
response["msg"] = "修改失败!"
response["code"] = 500
response["err"] = "ID 不能为空!"
}

c.Data["json"] = response
c.ServeJSON()
c.StopRun()
}

func (c *ArticleController) Delete() {
id, _ := c.GetInt("id", 0)

response := make(map[string]interface{})

o := orm.NewOrm()
obj := models.Article{Id: id}

if _, err := o.Delete(&obj); err == nil {
response["msg"] = "删除成功!"
response["code"] = 200
}else{
response["msg"] = "删除失败!"
response["code"] = 500
response["err"] = err.Error()
}

c.Data["json"] = response
c.ServeJSON()
c.StopRun()
}
```

Model ```Article.go```代码
```
package models

import (
"github.com/astaxie/beego/orm"
"time"
)

type Article struct {
Id int
Title string
BusinessType string
BusinessName string
DemandType string
Province string
City string
District string
Address string
Content string `orm:"type(text)"`
PublisherId float64
PublishDate time.Time `orm:"type(datetime)"`
Created time.Time `orm:"auto_now_add;type(datetime)"`
}

func init() {
// 需要在init中注册定义的model
orm.RegisterModel(new(Article))
}
```

> 实现上可能会存在很多的缺点不足,希望各位大佬不吝赐教。最后如果大家有觉得还有一点点存在的价值的话给个星星鼓励一下谢谢各位。Github:https://github.com/1920853199/go-gii