免费可以测试的vps服务器资源?

回复

xiaodu2017 回复了问题 • 2 人关注 • 1 个回复 • 91 次浏览 • 39 分钟前 • 来自相关话题

分享下一点创业小心得以及创业项目运营情况

qixinghaitang 发表了文章 • 1 个评论 • 75 次浏览 • 4 小时前 • 来自相关话题

之前发过一个文章介绍我的创业小项目,但是可能还是有部分同学没有看到,所以在分享运营情况之前还是重新介绍下我的创业项目:

小专栏:一个专业人士的创作知识社区,旨在为一些在某个领域有深度研究的小伙伴提供的写作平台。后续小专栏会推出新功能,我们愿... 查看全部

之前发过一个文章介绍我的创业小项目,但是可能还是有部分同学没有看到,所以在分享运营情况之前还是重新介绍下我的创业项目:


小专栏:一个专业人士的创作知识社区,旨在为一些在某个领域有深度研究的小伙伴提供的写作平台。后续小专栏会推出新功能,我们愿景就是要改变技术人购买实体技术书的传统方式。


小专栏地址:https://xiaozhuanlan.com/


小专栏从8月1号开始内测到现在一共50天:


1、截止今天通过申请的专栏有将近130个,大多数专栏作者都是来自小米、腾讯、华为、阿里巴巴、百度、亚马逊、今日头条、欢聚时代、网易的技术产品设计牛人,也有如网易UEDC设计团队、又拍云技术团队、Ucloud 技术团队开设的团队专栏。


2、截止今天一共有1717次付费订阅共33691元,付费订阅次数最高的专栏如下:



还有剩下几十个两三百块钱订阅的专栏不一一罗列......


3、通过微信、Github、微博授权登录的用户是11067人,小专栏平台公众号也获得了超过7000人的订阅,希望大家可以多多支持,微信搜索“小专栏平台”关注支持一下哈。


4、成本:小专栏是我在今年四月份辞职之后全职做的,主要成本除了注册公司、各种认证花费将近一万元之外,其余都是人力成本,比如我接近6个月没有工资,薪资损失大概就18万了,还有一些设计费用等等加起来大约在二十六七万吧。


创业心得:


1、之前总结的一句话,那就是“如果看到一个平时还蛮骄傲的人哪怕再忙都跟每一个人/每一个群很有耐心聊天说话,那这个人肯定刚刚创业”。像小专栏这样的平台需要很多优秀的作者,需要不断邀请各类大牛加入平台,经常会遭受到各种拒绝,被拒绝其实也是需要一颗强大内心承受的。


2、每天想着如何能够让小专栏这个项目坚持20-24个月;在我钱少人少如何做到最好;后续的一些产品规划;等等。


3、在50天内测期间,我对小专栏付费率还是满意的吧,但是也时常会想做小专栏我怎么赚钱啊?万一20个月过去之后,我无法做到维持盈亏的话怎么办呢?


最后对自己说一句话:


坚持吧,少年!加油吧,少年!


也欢迎大家给建议、提意见,么么哒

使用bcc分析函数耗时

lrita 发表了文章 • 0 个评论 • 31 次浏览 • 4 小时前 • 来自相关话题

golang自带的pprof工具只能分析定性分析哪些代码时最热(最占用CPU)的代码,通常低调用次数+高耗时的方法会被高调用次数的方法淹没掉。因此我们需要一些方法能够比较准确的... 查看全部

golang自带的pprof工具只能分析定性分析哪些代码时最热(最占用CPU)的代码,通常低调用次数+高耗时的方法会被高调用次数的方法淹没掉。因此我们需要一些方法能够比较准确的获知某个函数具体消耗的多少时间。
https://lrita.github.io/2017/09/16/get-function-elapse/

看到一个用Go语言编程的众筹机器人项目

Comdex 发表了文章 • 1 个评论 • 197 次浏览 • 1 天前 • 来自相关话题

https://z.jd.com/project/details/89271.html

好像还不错,大家怎么看

https://z.jd.com/project/details/89271.html


好像还不错,大家怎么看

一个多功能心跳发送包——yapool

千手扉间 发表了文章 • 0 个评论 • 153 次浏览 • 2017-09-14 19:42 • 来自相关话题

自己实现了一个多功能心跳包

传送门 https://github.com/CrocdileChan/yapool

因为之... 查看全部

自己实现了一个多功能心跳包


传送门 https://github.com/CrocdileChan/yapool


因为之前的项目需要,我将一部分功能逻辑抽象出来,这个包可以供给做分布式的小伙伴用来造轮子。


基于这个包,可以轻易的实现服务发现、健康监测以及集群数据采集功能,心跳可以分为多个等级,开发者可以在里面定义自己需要传送到center(或者叫master)的讯息,center端可以对该信息进行处理。

go 语言操作数据库 CRUD

leyafo 发表了文章 • 2 个评论 • 330 次浏览 • 2017-09-07 18:38 • 来自相关话题

文章原链:http://www.leyafo.com/post/2017-09-07-go-db-crud/


go 语言标准库已经提供数据库访问通用接口,不同数据库需搭配相应连接 Driver。标准库里面 database/sql 实现基本数据类型 Scan, 基本的 Transaction 以及 sql 参数化。用这些东西去操作数据库完全够用,只是随着项目代码增长,sql string 会蔓延到项目的各个角落。若要修改数据库表结构,这些 sql string 就是噩梦一般存在。流行做法是使用 ORM(Object Relational Mapping) 去解决这个问题。ORM 封装好一些 CRUD 基本操作,可以避免大量手写 sql string.


go 编译型语言,无法做到像 Ruby 里面的 Method Missing 这样动态特性,可以为一个复合类型的 struct 随时添加一个 field. go 社区使用的 ORM 还是需要事先手动添加好 Field. 这样做需要对数据库和 struct 的成员做很多约定,写好对应的访问 tag。这些仍然无法避免修改数据库表时要一齐修改 go 代码。


我们可以仔细想想 ORM 真的是唯一的选择吗?ORM 实际上无法完美操作数据库,它做的事情无非就是这些事情:



  1. 参数化 sql string。

  2. 封装一些简单的 CRUD 操作。

  3. 序列化 sql 查询结果。


对于一些复杂的数据库查询语句,任何强大的 ORM 库,灵活的动态语言特性都无法解决。况且 ORM 也未必是好东西,它简化了操作,却间接隐藏了数据库的一些功能。如果不脱离 ORM 依赖我们无法去更好的操作数据库,去自己优化查询语句。以 go 语言目前的特性来看,这个社区永远也不可能会做出能像动态语言那样灵活的 ORM。关于 ORM 与 go 语言更详细的吐槽请见这里


如果不用 ORM 我们碰到的无非是上面提到的 3 个问题而已。把这个三个问题掰开处理,第一个问题是不存在的。参数化 sql string 这件事情我们只需要小心的处理就能防止 sql 注入这样的安全问题。剩下的就是 2 和 3 的问题,而第二个问题我们暂时也不需要解决,我们一开始就去写一些重复代码好了。而问题 3 我们可以手动自己去序列化,也可以用社区的一些库去解决这个问题。社区已经有了不错的解决方案,我用的就是 sqlx 去解决的这个问题。


当初项目开始时我考察不少 ORM 库后,果断抛弃使用 ORM。项目经过一段时间迭代后,不用 ORM 没有特别明显的不便。唯一的问题就是我需要手动为每一张表做好 table 到 go struct 之间的映射。需要写非常多重复性的 CRUD 操作代码。这些代码很难使用统一方法减少重复,只好任其膨胀。直到有一天我看到这篇文章,原来 go 语言需要写重复代码这个问题在其他问题领域也存在,而社区老司机们解决这个问题的方式是使用机器生成代码。社区大范围这么做的原因是 go 语言的语法非常简单,很容易用 go 生成 go 代码。


写 CRUD 生成器思路很简单,只需要去数据库里查询 table 的详细信息,为不同的 column 数据类型映射 go 数据类型。最后用 go 的 template 实现一些简单的 CRUD 方法。对于一般的 select 查询语句我这里没有去做实现,因为不同的表查询条件是不一样的,这种差异用函数传参解决会更好。生成器做 column 映射和拼接查询语句是极好的。


最后在项目里面把生成器生成的代码和手写的数据库相关代码分离开来,以方便数据库表结构变动后可以让生成器重新生成代码。这里是我写的这个简单的生成器,参照了一部分 xo 项目的代码,由于我只支持 Postgresql, 没有去支持 join 和 has_many 这样的操作,代码相对他们要简单很多。


事情到这里并没有完,我们还需要序列化后的查询结果做一些反序列化的工作,go 语言的 struct tag 对这方面有很好的支持。可是我们用机器生成的代码是无法控制外界需要的各种反序列化的字段。下面以序列化 json 为例,我们并不想把数据库的 ID 字段暴露给外界。如果用生成器去控制这些配置,生成器需要做更多的配置,数据库表字段需要更多约定,这无疑会增加生成器的难度。我们必须要为每一张表手动单独做一个 Export 的结构体与方法,以满足各种其他序列化的要求。


type UserExport struct {
Name string `json:"name"`
Email string `json:"email"`
UpdatedAt string `json:"updated_at"`
}

func (u User) Export() UserExport {
return UserExport{
Name: u.Name,
Email: u.Email,
UpdatedAt: u.UpdatedAt,
}
}

func (u User) MarshalJSON() ([]byte, error) {
return json.Marshal(u.Export())
}

如上所示,我们可以为 User 表配置不同 field 和 tag。可以单独为不同的序列化数据类型写一个 Marshal 方法,这些都是手动可以控制。为了灵活我们还可以把 Export 这个结构体直接嵌入到其他结构体中,不用担心 Marshal 会继承式覆盖后面 Marshal 方法。

Jetbrains 家族利器之 Gogland 简明教程

bingohuang 发表了文章 • 8 个评论 • 580 次浏览 • 2017-09-05 10:03 • 来自相关话题

gogland.png

喜欢用 IDE 做开发的同... 查看全部

gogland.png


喜欢用 IDE 做开发的同学必定不能错过 Jetbrains 家族的 IDE,款款精品,可谓都是 IDE 中的神兵利器。


这里介绍该家族 又一款新的 IDE —— 用于开发 Go 语言 的 Gogland,喜欢折腾 Go 语言 IDE 的同学一定要试试看。


一、下载 Gogland


该步骤非常简单,访问 Gogland 的下载页面,下载相应平台的安装包即可,三大平台(Mac、Linux、Windows)都有支持。


注:当前 Gogland 还是预发布版,想了解更多 Gogland 信息,请参考附录二


二、安装 Go 环境


接下来需要安装相应的 Go 环境,才能在 Gogland 中开发 Go 程序。


安装方法多样,首先可参考官网安装指南,但如果你有 Go 多版本的需求(比如新老版本共存),你想简化 Go 配置过程(省去GOPATH、GOROOT等的配置),你还希望它支持跨平台(支持Mac和Linux),那么我特别推荐这款 Go 环境安装工具:GVM —— 详情可参考我的写的这篇文章《Go 语言多版本安装及管理利器 - GVM》


二、设置工作空间


用过 Eclipse 的同学必不陌生 Workspace (工作空间),Go 也有自己的工作空间,建议将 Go 的代码放在一个单独的空间,类似布局如下:


- workspace
- bin
- pkg
- src
- github.com
- user_name
- project1
- project2

然后将该工作空间(workspace 所在目录)设置到 GOPATH 当中。GOPATH 可用于 Go 导入、安装、构建和更新,还会被 Gogland 自动识别(见第四节)。


注:如果你采用上述说的 GVM 的安装方式,将自动创建一个 Workspace,并配置好 GOPATH 等相关环境变量,这也是 GVM 方便的地方。


三、设置 Gogland 的 GOROOT


在 Gogland 中,需要配置当前项目的 GOROOT,用来编译运行 Go 代码。配置起来也非常方便,打开 Settings → Go → GOROOT 设置即可:


gogland-goroot.png


如果你本地安装了多个版本的 Go,也可以在右侧下拉选择相应的版本,这依赖于你本地有多个版本的 Go 环境了。


四、设置 Gogland 的 GOPATH


Gogland 中的 GOPATH 设置功能非常实用和强大,你既可以配置多个全局的 GOPATH (IDE 会自动识别环境变量中的 GOPATH,可不勾选),也可以配置多个项目级别的 GOPATH,甚至还可以配置多个模块级别的 GOPATH。打开 Settings → Go → GOPATH 设置如下:
gogland-gopath.png


五、建立新的 Go 项目


这个很简单,在主菜单选择 File → New → Project, 继而弹出 New Project 设置向导:
gogland-new-project.png


此处就需要选择你在上面配置好的 GOROOT,新建的项目会自动关联全局 GOPATH,你还可以参照第四节说是设置你项目的 GOPATH


五、导入已有 Go 项目


如果你本地已有 Go 项目代码,只需在主菜单选择 File → Open,打开你的项目目录即可。


最新版的 Gogland有一个非常体贴的小功能,会自动匹配你当前设置好的全局 GOROOT。当然,你也可以在设置中更换。


接下来会开始建立索引(index),第一次建立的时候可能会比较慢,CPU消耗比较大,耗时长短依赖于你工作空间的代码量,但后续用起来就非常快捷了,索引的建立也是增量的。


注: 但也有一个问题,每次升级 gogland 或者安装更新插件,也会重新建立索引,这个确实不友好,希望 Jetbrains 后续能改善这点。


七、运行/调试/测试程序


当你有了一个 Go 项目工程,二话不说,先跑跑看(前提是你要有一个可执行入口,在 main package 下的 main 函数)。


为了在 Gogland 运行一个 Go 程序,你需要用到 Run Configuration。使用方法如下:



  • 在主菜单栏或工具栏打开:Run → Edit Configurations

  • 点击 Edit Configurations,打开 Run/Debug Configuration 对话框

  • 点击 + 号按钮,选择你需要的运行配置,Go 用到的配置类型如下(按使用频率解释):
    gogland-run-config.png

    1. Go Application:相当于执行 go build 和运行可执行文件命令,该配置会生成可执行文件,也可执行debug

    2. Go Single File:相当于 go run 命令,该配置不会生成可执行文件,不能执行 debug

    3. Go Test:用于运行测试代码,相当于 go test,有三种测试框架可供选择:gotest,gocheck 和 gobench

    4. Go Remote:提供了 Go 的远程调试支持,你只需要设置要远程连接的 Host 和 Port,并且保证你要调试的程序是通过 Delve 启动的

    5. Go App Engine:允许你将程序部署到 Google AppEngine,前提是你有使用 Google 云,并且你的程序模块加载了 Go AppEngine SDK



以上就是 Go 工程在运行/调试/测试过程中会用到的配置类型,特别是前三项,最为常用。


如果你要运行程序,推荐使用1和2。而 Gogland 智能的地方在于,你可以通过鼠标右击这样快捷的方式来运行和配置,如下,在有 main 函数的地方右击即可:
gogland-run.png


如果你要调试程序,本地调试可用1,远程调试请使用4。


如果你要测试程序,请使用第3种方式。


同时,在测试程序的基础上,你还可以执行调试和代码覆盖率统计,功能十分强大!


gogland-run-coverage.png


总的来说,Gogland 继承了 Jetbrains 家族的基因,完全可以作为 Go 语言编程的神兵利器,还不赶紧来试试看


注:提供两个附录,让大家更全面的了解 Gogland。


附录一:常用辅助快捷方式:以 Mac 为例



  1. 查看提示帮助:默认快捷键是 ⌥⏎。最常用的快捷键之一,从 Eclipse 转过来的同学对该快捷键肯定不陌生,很多地方都可以用上该快捷键,特别是有错误的时候,有时还会有意想不到的好效果哦。

  2. 查看声明:按住 Cmd 健(Windows 下是 Ctrl键),鼠标左键点击相关标识。最常用的快捷键之一,跳转声明、查看源码必不可少。

  3. 查看函数参数:⌘P。直接在当前函数下查看,当然你也可以用上面的查看声明方式跳转过去查看。

  4. 代码重构:在你需要重构的地方,右击选择 Refactor 即可。

  5. 查看使用率:在你需要查看使用率的地方,右击选择 Find Usages 即可。

  6. 还有一个非常赞的功能,就是设置 live template,使用方式就是:缩写 + Tab 键。配置方式在 Settings → Editor → Live Templates 中,Go 也内置了不少快捷模板哦。


以上快捷键你都可以在 Settings → Editor 中查找或重置,更多 Intellij IDE 的使用小技巧可以查看:Discover IntelliJ IDEA


附录二:常见问题


1、Gogland 代表什么?


Gogland 是一个代号,并不是最终的产品名称。灵感来自于芬兰湾的一座小岛,离芬兰湾另一座小岛 Kotlin(也是 Jetbrains 推出的一门语言) 不远。


2、Gogland 是否会开源?


当前没计划开源。


3、Gogland 是否免费?


当前预览版免费,正式版还是要收费的。


4、Gogland 中的 Go 插件是否能用于其他基于 IntelliJ 的 IDE?


可以的,这个 Go 官方插件 和 Gogland 所带的 Go 相关功能是一致的,可用于 IntellIJ IDEA 极限版和其它付费 IDE,不过还不能用于社区版。


5、Gogland 绑定了哪些其他 IntelliJ 插件?


Git, Terminal, Textmate, JavaScript, CSS, HTML, Database Tools 和 Coverage 等。


6、Gogland 什么时候正式发布?


还没有确切时间,预计每个月会发布一个 EAP build 版本。欢迎多多给我们反馈


7、我在哪里可以提交 issues 和功能需求?


请使用 Gogland 的 issue 跟踪:https://youtrack.jetbrains.com/issues/GO

Node.js 之父 Ryan 推薦大家使用 Go 語言,而不是 Node.js

appleboy 发表了文章 • 4 个评论 • 807 次浏览 • 2017-09-05 09:34 • 来自相关话题

『Node.js 之父 Ryan 目前在 Google Brain 一手建立 Node.js 世界,但是在訪談中,竟然推薦大家使用 Go 語言,而不要使用 Node.js 當作後端 (假如您想要建構一個龐大的系統)。內文中提到 Node.js Callb... 查看全部

『Node.js 之父 Ryan 目前在 Google Brain 一手建立 Node.js 世界,但是在訪談中,竟然推薦大家使用 Go 語言,而不要使用 Node.js 當作後端 (假如您想要建構一個龐大的系統)。內文中提到 Node.js Callback 的缺陷在 Node.js 出現了 async 了有效了解決大量使用 Callback。Ryan 也非常驚訝地說,他沒想到在 Node.js Client 端竟然如此熱門。要建立小量的開發系統,他非常推薦使用 Node.js,但是如果您要建立龐大的分散式 DNS 系統,我覺得不會推薦你使用 Node。』


說到 Client Side 工具,在 Node.js 世界的確在 Web 領域佔有一席之地,就像我現在在寫 Go,也是大量使用 Node.js 工具 (像是 Webpack, Gulp, Imagemin 等圖片壓縮工具) 來幫助建置 Web 網站。


詳細原文可以參考: https://www.mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/

这个就是我做了三四个月的产品啦,欢迎提意见哦

qixinghaitang 发表了文章 • 2 个评论 • 366 次浏览 • 2017-09-01 12:48 • 来自相关话题

小专栏 :https://xiaozhuanlan.com/

主打付费专栏,如果你非常喜欢写作,且拥有重多粉丝读者,欢迎开开设付费专栏哟。如果你觉得不好意思收费... 查看全部

小专栏 :https://xiaozhuanlan.com/


主打付费专栏,如果你非常喜欢写作,且拥有重多粉丝读者,欢迎开开设付费专栏哟。如果你觉得不好意思收费,但是感觉自己写的东西很棒,那么你也可以来开设免费专栏。


但是小专栏最看重的还是您专业的分享,无论关于技术、产品或者运营方面。


推荐一些目前比较不错的专栏


iOS


1、iOS 成长之路 目前已经收获了超过5500元啦
面向读者:笼统的说就是面向初中级 iOS 开发者。你可能是一个刚刚入门能够熟练使用 UITableView 的新手,也可能是做了一两年对于 UIKit 和 Foudation 的 API 都已经很熟悉了,想要提高自己的开发者。或者是能实现工作中的业务需求,但是对如何提升自己还有些迷茫的开发者们。


2、iOS成长之路3期·WWDC17内参也已经有超过2800元的订阅了
本书的内容主要介绍 WWDC 17 上提到的和 iOS 开发相关的开发技术。


Android:


0、解读Android系统架构



  • 从源码角度,带领大家一睹Android系统架构;

  • 从App到framework,native,乃至Linux内核;

  • 从上至下地深度解读Android架构设计。


在过去的一年,对于Android从底层一路到上层有不少自己的理解和沉淀,把知识进行归档整理与再学习,从而加深对Android架构的理解。通过前面对系统启动的介绍,相信大家对Android系统有了一个整体观,接下来需要抓核心、理思路,争取各个击破。


关于作者:Gityuan,Android系统工程师,曾就职于IBM、Lenovo,目前就职于小米MIUI系统组


文章总数:接近110篇深度技术解析,出版成书大概是两本500页左右的书籍厚度。


专栏定位: 基于Android 6.0的源码,专注于分享Android系统原理、架构分析的原创文章。


建议阅读群体: 适合于正从事或者有兴趣研究Android系统的工程师或者爱好者,也适合Android App高级工程师; 对于尚未入门或者刚入门的App程序员阅读可能会困难些,可能不是很适合。


1、《Android 开源库的源码导读》
包含 Retrofit 、 Okio、OkHttp、RxJava 原理剖析。作者 Piasy 清华大学计算机系,目前就职于 YOLO,带领安卓团队。同时作者还有免费专栏《Android 架构系列》《Piasy 的 WebRTC 专栏》


2、《轻松在 VPS 搭建 Shadowsocks 科学上网》 作者键盘男,悦跑圈Android 开发工程师。本文收录于《键盘男的 Android 开发心得》


3、《Android 插件化原理解析》 作者田维术,前360,现蚂蚁金服Android工程师。以下为专栏内容。


4、《安卓自定义 View 教程》作者GcsSloop, 一名生活在2.5次元的魔法师,我一直在致力于研究基础魔法,并且始终坚信利用这些基础魔法,可以创造出华丽而又强大的高级魔法。以下为专栏内容简介。


5、《Kotlin Primer》 Kotlin 开发入门指南,专栏还将不断更新下去。作者张涛,沪江网 Android 开发工程师,知名博主。


6、《Android 开发实战》 开发过程中的一些实战经验,饱含各种进阶的技巧和知识,作者 D_clock爱吃葱花 ,欢聚时代Android 开发工程师,知名博主。


产品:


WinsonL的产品技能树
魅族产品经理的专栏,用实例干货分享产品技能树,完全可操作,不刻意抽象深奥化。


设计:


Google对话式交互规范指南,作者资深UX设计师、猫奴,曾就职于淘宝UED、腾讯ISUX设计中心、猎豹UX设计中心。
语音交互(voice interaction)和人工智能(AI)是目前互联网行业非常热门的话题,对于体验设计师来说,这是一个比较新的领域,行业与设计标准还未完全成型。Google作为行业先驱,针对对话UI体验提供了一系列设计原则、流程与方法的具体建议和归纳,本专栏文字翻译自Google官方对话式交互规范指南,为相关领域的开发者和设计师提供了比较基础的指导和框架。


欢迎大家体验和提建议哦

golang web流量统计 上

tupunco 回复了问题 • 3 人关注 • 3 个回复 • 488 次浏览 • 2017-08-30 08:04 • 来自相关话题

go 1.9 多线程安全MAP 函数模块

alalmn 发表了文章 • 0 个评论 • 454 次浏览 • 2017-08-28 16:02 • 来自相关话题

package main

//go 1.9  多线程安全MAP  函数模块
//QQ:29295842  欢迎技术交流
import (
    //  "fmt"
    "s... 			查看全部
					
package main

//go 1.9 多线程安全MAP 函数模块
//QQ:29295842 欢迎技术交流
import (
// "fmt"
"sync"
)

var (
map_list sync.Map //广告配置信息
wgx sync.WaitGroup //
)

func Thread_map_add(id string, rows_map map[string]interface{}) { //添加数据
map_list.Store(id, rows_map)
}

func Thread_map_revise(id string, rows_map map[string]interface{}) { //修改
wgx.Add(1) //线程数
go func() {
map_list.LoadOrStore(id, rows_map) //修改
wgx.Done()
}()
wgx.Wait() //等待
}

func Thread_map_delete(id string) { //删除
wgx.Add(1) //线程数
go func() {
map_list.Delete(id) //删除
wgx.Done()
}()
wgx.Wait() //等待
}

func Thread_map_read(id string) (bool, string, map[string]interface{}) { //读取
read_bool := false
value := make(map[string]interface{})
value2, err := map_list.Load(id) //key读取
if err {
if valuexa, ok := value2.(map[string]interface{}); ok {
value = valuexa
read_bool = true
}
}
//fmt.Print("===%v==%v==\n", data, err)
//遍历读取
// map_list.Range(func(key, value2 interface{}) bool { //读取数据
// fmt.Println(key, "-----------", value2)
// // if valuexa, ok := value2.(map[string]interface{}); ok {
// // read_bool = true
// // //key = fmt.Sprintf("%v", key)
// // value = valuexa
// // }
// return true
// })
return read_bool, id, value
}

//fmt.Println("----------------")

// rows_map := make(map[string]interface{})
// rows_map["db_name"] = "098765"
// rows_map["list"] = "1234567"

// map_add("abc", rows_map)
// rows_map = make(map[string]interface{})
// rows_map["db_name"] = "aaaaaa"
// rows_map["list"] = "bbbbbbb"
// //map_add("123", rows_map)
// map_revise("abc", rows_map)
// rows_map3 := make(map[string]interface{})
// rows_map3["db_name"] = "rrrrr"
// rows_map3["list"] = "eeeeeee"
// map_add("1234", rows_map3)

// read_bool, key, re_map := map_read("abc")
// fmt.Printf("==%v==%v==%v==\n", read_bool, key, re_map["db_name"])

redis 分布式锁

toukii 发表了文章 • 0 个评论 • 266 次浏览 • 2017-08-26 12:48 • 来自相关话题

rddlock

github.com/everfore/rddlock

redis distribute lock

... 查看全部

rddlock


github.com/everfore/rddlock


redis distribute lock


redis 分布式锁, 实现原理:redis分布式锁


Usage


Lock & UnLock


lockkey := "lock-key"
timeout_ms := 3000

locked, ex := rddlock.Lock(rds, lockkey, timeout_ms)
defer reelock.UnLock(rds, lockkey, ex)

LockRetry


retry_times := 10
locked, ex := reelock.LockRetry(rds, lockkey, timeout_ms, retry_times) // get lock by retry
defer reelock.UnLock(rds, lockkey, ex)

UnLockUnsafe


直接删除key,可能会有问题:若删除之前,该key已经超时且被其他进程获得锁,将会删除其他进程的锁;删除之后,锁被释放,进而会有其他进程2获得锁。。。雪崩


locked, _ := rddlock.Lock(rds, lockkey, timeout_ms)
defer reelock.UnLockUnsafe(rds, lockkey)

SyncDo 异步执行任务


err := SyncDo(rds, lockkey, timeout_ms, func(timeout chan bool) chan bool {
ret := make(chan bool, 1)
go func() {
fmt.Println("doing...")
// TODO SOMETHING
select {
case <-timeout:
// do the rollback
break
case ret <- true:
fmt.Println("success end.")
}
}()
return ret
})

test


success:200, avg:1.1074123 ms
failed:0, avg:NaN ms
--- PASS: TestLockTime (10.59s)

#local-redis
=== RUN TestLockRetryTime
success:200, avg:1.1741205 ms
failed:0, avg:NaN ms
--- PASS: TestLockRetryTime (10.58s)

#uat-redis
=== RUN TestLockRetryTime
success:200, avg:12.572702 ms
failed:0, avg:NaN ms
--- PASS: TestLockRetryTime (10.59s)

欢迎指正 github.com/everfore/rddlock

PHP编码gzdeflate与Golang解码DEFLATE

qiangmzsx 发表了文章 • 0 个评论 • 139 次浏览 • 2017-08-25 00:00 • 来自相关话题

8月7日@黄同学找我问:“数据存到redis是gzdeflate压缩过的数据,golang从redis取出来,解压缩失败”。很多从PHP转Golang的业务经常会遇到,所以写下这篇博文,希望可以帮助更多人。
想要使用golang解码php的编... 查看全部

8月7日@黄同学找我问:“数据存到redis是gzdeflate压缩过的数据,golang从redis取出来,解压缩失败”。很多从PHP转Golang的业务经常会遇到,所以写下这篇博文,希望可以帮助更多人。

想要使用golang解码php的编码,那么就应该需要知道gzdeflate函数的算法是什么,先到gzdeflate文档,查看了一下发现:

gzdeflate使用的是纯粹的DEFLATE格式。这就与golang的compress/flate包一致了。有了了解就可以看着golang文档实现代码了。遂与@黄同学同学写了几个函数进行验证,最后定稿如下:


package main

import (
"strings"
"fmt"
"compress/flate"
"bytes"
"io/ioutil"
"github.com/bitly/go-simplejson"
)

func main() {

str:="test123"
b:=Gzdeflate(str,-1)
ss:=Gzdecode(string(b))
fmt.Println(ss)
}

// 解码
func Gzdecode(data string) string {
if data == "" {
return ""
}
r :=flate.NewReader(strings.NewReader(data))
defer r.Close()
out, err := ioutil.ReadAll(r)
if err !=nil {
fmt.Errorf("%s\n",err)
return ""
}
return string(out)
}

// 编码
func Gzdeflate(data string,level int) []byte {
if data == "" {
return []byte{}
}
var bufs bytes.Buffer
w,_ :=flate.NewWriter(&bufs,level)
w.Write([]byte(data))
w.Flush()
defer w.Close()
return bufs.Bytes()
}

// 编码
func GzdeflateForString(data string,level int) string {
if data == "" {
return ""
}
var bufs bytes.Buffer
w,_ :=flate.NewWriter(&bufs,level)
w.Write([]byte(data))
w.Flush()
defer w.Close()
return bufs.String()
}

经过@黄同学同学测试可以正确使用。留下wiki供后续遇到的同学查看。

快速搭建微服务--手把手教你服务发现与注册

wangxingge 发表了文章 • 2 个评论 • 438 次浏览 • 2017-08-24 19:23 • 来自相关话题

Build MicroService Platform --- Service Register and Discovery

Docker + Etcd + Registrator + App

现在的微服务很火,网络上... 查看全部

Build MicroService Platform --- Service Register and Discovery


Docker + Etcd + Registrator + App


现在的微服务很火,网络上各种文章也特别多,准备写一个快速搭建微服务的系列文章,读本文之前最好有点微服务的基础知识,这样比较好理解,以Golang为开发语言(因为这个目前比较火哈)

今天下午有时间就写第一部分,微服务的服务注册与发现,下次准备写Gate相关的分享。



  • 本文原创: 王星鸽,转发请加入原创建链接

  • 使用Centos7 的虚拟机, IP: 192.168.196.88

  • 在安装Docker 之前,还是先关闭防火墙吧,因为有很多的端口需要开

  • 搭建环境的时候要了解基本的使用docker命令。

  • 本文共分5部分

    • 安装 Docker

    • 安装 etcd

    • 安装 etcd-viewer

    • 安装 registrator

    • 测试



一、安装 Docker



  1. 从阿里云安装Docker: curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -

  2. 设置镜像加速(在国内很多东西会被墙,建议使用镜像加速)

    1. 首先要有自己的阿里云账户(当然是免费的)

    2. 在阿里云中找到镜像仓库-> Docker Hub 镜像站点-> 您的专属加速地址

    3. 执行加速器配置脚本, 别忘了把地址换成 "您的专属加速地址"
      sudo mkdir -p /etc/docker
      sudo tee /etc/docker/daemon.json <<-'EOF'
      {
      "registry-mirrors": ["your-mirror-address"]
      }
      EOF
      sudo systemctl daemon-reload
      sudo systemctl restart docker



二、安装 Etcd



  1. 下载 etcd 地址: https://github.com/coreos/etcd/releases


  2. 搭建 etcd 的容器,因为要搭建的是etcd 集群,所以要创建多个etcd容器,我们用3个。



    1. 写 Dockerfile, 当然用官方的 Iamge 也可以。


    FROM centos:7

    COPY etcd /opt/etcd/etcd

    RUN chmod +x /opt/etcd/etcd

    EXPOSE 2379 2380

    CMD ["/opt/etcd/etcd"]


    1. Build Image: Docker build -rm -t etcd_image ./

    2. 启动容器,etcd启动参数详解


    # 启动容器1
    dk run --name ec_1 -p 12379:2379 -p 12380:2380 -d etcd_image \
    --name ec_node_1 \
    --listen-peer-urls http://0.0.0.0:2380 \
    --listen-client-urls http://0.0.0.0:2379 \
    --advertise-client-urls http://192.168.196.88:12379 \
    --initial-advertise-peer-urls http://192.168.196.88:12380 \
    --initial-cluster-token etcd-cluster-1 \
    --initial-cluster ec_node_1=http://192.168.196.88:12380,ec_node_2=http://192.168.196.88:22380,ec_node_3=http://192.168.196.88:32380 \
    --initial-cluster-state new

    # 启动容器2
    dk run --name ec_2 -p 22379:2379 -p 22380:2380 -d etcd_image \
    --name ec_node_2 \
    --listen-peer-urls http://0.0.0.0:2380 \
    --listen-client-urls http://0.0.0.0:2379 \
    --advertise-client-urls http://192.168.196.88:22379 \
    --initial-advertise-peer-urls http://192.168.196.88:22380 \
    --initial-cluster-token etcd-cluster-1 \
    --initial-cluster ec_node_1=http://192.168.196.88:12380,ec_node_2=http://192.168.196.88:22380,ec_node_3=http://192.168.196.88:32380 \
    --initial-cluster-state new

    # 启动容器3
    dk run --name ec_3 -p 32379:2379 -p 32380:2380 -d etcd_image \
    --name ec_node_3 \
    --listen-peer-urls http://0.0.0.0:2380 \
    --listen-client-urls http://0.0.0.0:2379 \
    --advertise-client-urls http://192.168.196.88:32379 \
    --initial-advertise-peer-urls http://192.168.196.88:32380 \
    --initial-cluster-token etcd-cluster-1 \
    --initial-cluster ec_node_1=http://192.168.196.88:12380,ec_node_2=http://192.168.196.88:22380,ec_node_3=http://192.168.196.88:32380 \
    --initial-cluster-state new


  3. 至此我们的 etcd集群搭建完成了。


三、安装 Etcd-viewer




  1. 搭建 etcd-viewer 的容器,直接从官方拉镜像:



    1. docker run -d -p 18080:8080 nikfoundas/etcd-viewer

    2. 访问etcd-viewer: http://192.168.196.88:18080



  2. 在etcd-viewer 中添加registry,成功之后如下图所示

    1. ec_1, http://192.168.196.88:12379

    2. ec_2, http://192.168.196.88:22379

    3. ec_3, http://192.168.196.88:32379



etcd-viewer


四、安装 Registrator



  1. 获取 Registrator镜像: docker pull gliderlabs/registrator

  2. 启动 Registrator容器,Registrator启动参数详解
    docker run -d --name=registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest etcd://192.168.196.88:12379

  3. 启动之后,就可以看见在当前宿主机启动着的所有容器,通过etcd-viewer就可以看到。

    etcd-viewer-registrator

  4. 至此 docker + etcd + etcd-viewer + registrator, 这个基于docker的服务注册的环境搭建完成了。


五、测试Service Registrator环境



  1. 写一个简单的Golang 的http服务,并编译生成可执行文件


package main

import (
"net/http"
"github.com/julienschmidt/httprouter"
"log"
)

func High(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("done"))
}

var (
router = httprouter.New()
)

func main() {
router.GET("/test", High)
log.Fatal(http.ListenAndServe("0.0.0.0:80", router))
}


  1. 写 Dockerfile 来生成测试服务的镜像,写好就生成镜像: docker build --rm -t simple-http ./


FROM alpine:latest

RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

COPY simpleService /opt/simpleService

RUN chmod +x /opt/simpleService

EXPOSE 80

CMD ["/opt/simpleService"]



  1. 创建并启动容器,我们测试的时候启动3个。



    1. docker run --name http_1 -d -P simple-http

    2. docker run --name http_2 -d -P simple-http

    3. docker run --name http_3 -d -P simple-http



  2. 创建完以后再查看容器是否都启动成功,docker ps -a

  3. 验证服务注册成功到etcd中,查看 etcd-viewer: http://192.168.196.88:18080

    etcd-test-service-1

    etcd-test-service-2

  4. 可以看到我们的服务都已经自动的写到了etcd集群中。再做两个测试:

    1. 动态添加容器,etcd中可以看到新服务。

    2. 动态添加容器,etcd中可以看到服务减少。

    3. 停止某个etcd容器,etcd集群还可以正常发现服务。



服务注册与发现环境搭建完成

Golang Label使用方法

haohongfan 发表了文章 • 0 个评论 • 240 次浏览 • 2017-08-22 10:00 • 来自相关话题

发现golang的label也是比较强大的, 这里看了一些资料, 搜集了一些特点, 欢迎指正 http://www.haoho...