beego session 根本无法正常使用

有问必答edwinxie 回复了问题 • 5 人关注 • 2 个回复 • 1187 次浏览 • 2016-10-25 10:05 • 来自相关话题

gorm怎么连接mssql数据库?

有问必答haha 回复了问题 • 2 人关注 • 2 个回复 • 667 次浏览 • 2016-10-25 09:57 • 来自相关话题

goroutine 切换时如何切换栈?

有问必答傅小黑 回复了问题 • 3 人关注 • 2 个回复 • 483 次浏览 • 2016-10-25 09:13 • 来自相关话题

10.25 每日早报

文章分享astaxie 发表了文章 • 0 个评论 • 346 次浏览 • 2016-10-25 08:15 • 来自相关话题

10.25 每日早报

新闻:

1.Node.js包管理器npm 4.0发布,新增大量重要改进

2.奔驰分时租赁平台Car2Share随心开正式进驻SOHO中国,半小时租费9.9元

3.优步中国开始新... 查看全部

10.25 每日早报


新闻:


1.Node.js包管理器npm 4.0发布,新增大量重要改进


2.奔驰分时租赁平台Car2Share随心开正式进驻SOHO中国,半小时租费9.9元


3.优步中国开始新App首发版内测,上线人工客服、与微信完成对接


4.原Uber中国高级副总裁柳甄加盟今日头条,具体任职暂未透露


5.分时租赁平台嗒嗒用车获得2000万人民币的A轮投资占股10%,旗下均为新能源汽车


6.滴滴快车拼车发布业务数据,日均订单已突破200万单,平均拼成率达70%


7.大疆发布禅思Z30远摄变焦云台相机,支持30倍光变,面向行业无人机应用市场


8.GeekPwn2016黑客嘉年华在上海开幕,神奇小子Geohot携自动驾驶系统Comma One 2参会


资源:


阿里&BCG:人工智能,未来制胜之道
http://www.bcg.com.cn/cn/newsandpublications/publications/reports/report20161013001.html


注:上述内容来源于互联网,由EGO整理

函数里的 socket 连接没有被正确的关闭

有问必答astaxie 回复了问题 • 2 人关注 • 1 个回复 • 644 次浏览 • 2016-10-24 21:30 • 来自相关话题

有对验证码识别感兴趣的朋友吗?

有问必答gongxun 回复了问题 • 6 人关注 • 5 个回复 • 751 次浏览 • 2016-10-24 20:54 • 来自相关话题

使用API网关构建移动端友好的API服务

Go开源项目zhangxu 发表了文章 • 0 个评论 • 356 次浏览 • 2016-10-24 19:02 • 来自相关话题

移动端API服务的特点

大多数的移动端app,和后端都采用基于HTTP的JSON数据通信。相对于PC端,移动端的API服务最大的差异是网络环境。为了保证移动端的体验,通常后端API服务会为移动端的每个场景,定制API合并数据返回,减少移... 查看全部

移动端API服务的特点


大多数的移动端app,和后端都采用基于HTTP的JSON数据通信。相对于PC端,移动端的API服务最大的差异是网络环境。为了保证移动端的体验,通常后端API服务会为移动端的每个场景,定制API合并数据返回,减少移动端的请求,提高移动端的体验。


带来的问题


对于后端开发人员而言,提供高度可复用的原子的API接口是最理想的状态,但是对于移动端,就存在矛盾。


为了适应移动端的场景,后端API服务针对移动端的场景,定制API,在定制的API中合并数据结果。这样做虽然解决了移动端的问题,但是对于后端而言,会做很多枯燥,无聊的工作,毫无成就感,并且随着版本的迭代,会不停地去修改这些定制的门面API。


解决方案


对于这类情况,API 网关成为一个很好的解决方案。把服务聚合和定制的工作交给网关,后端提供原子类的API接口。笔者实现的Gateway的API网关正是这样的解决方案。


使用Gateway


Gateway是使用Go实现的API网关,支持API服务聚合的功能。我们使用一个例子来看看Gateway如何帮助我们更好地构建移动端友好的API服务。


背景


首先我们有一个会员的后端API服务提供了2个API服务:




  • /api/user/base?userId=xxx


    会员基本信息接口




  • /api/users/{userId}/account


    会员账户信息接口




在APP的个人信息页面上要同时显示这2类信息


备注:这里我为了演示Gateway的rewrite功能,上面的API接口URL设计并不好,有点乱。然而在现实情况下,这个2个接口有可能是两个系统提供,完全可能出现这种情况。


方案


首先,我们需要定义一个符合Restful规范的API,然后这个URL在网关上需要给转换成后端服务的2个API调用,并且合并结果返回。


创建2个Cluste


在gateway的admin管理系统上,创建2个Cluster,分别对应基本信息查询接口和账户信息查询接口后端server的集群。


创建真实后端Server


在gateway的admin管理系统上分别创建对应2个接口实现的真实后端Server的信息,其中最主要的信息就是ip和port


绑定操作


把真实server绑定到对应的Cluster上。


创建聚合URL


在Admin系统上创建一个聚合URL为:^/api/users/(\d+)/info$,这个是一个正则表达式。然后在这个聚合URL上创建2个聚合调用:分别对应2个真实API的提供Cluster




  • /api/user/base?userId=$1


    对应用户基本信息接口的后端集群:cluster1,同时设置返回的数据在聚合json的attr属性为:base




  • /api/users/$1/account


    对应用户账户信息接口的后端集群:cluster2,同时设置返回的数据在聚合json的attr属性为:account




效果


这个时候,APP 向gateway 请求 /api/users/10000/info,gateway的会拆分应用请求,同时调用设置好的2个调用,并且聚合数据返回:{"base": {基本信息返回的json}, "account": {账户信息返回的json}},然后返回给APP


以上简单介绍了API Gateway的作用,详细的介绍可以在github上查看Gateway项目

导入一个模块时前面 加一个下划线 是起到什么作用?

技术讨论ofttryaj 回复了问题 • 6 人关注 • 4 个回复 • 519 次浏览 • 2016-10-24 17:11 • 来自相关话题

Go编译出来的库是否可以提供库给Android和iPhone进行调用?

有问必答傅小黑 回复了问题 • 4 人关注 • 2 个回复 • 431 次浏览 • 2016-10-24 15:55 • 来自相关话题

最近要写爬虫,大家有推荐 Golang 的爬虫框架吗?

有问必答judas 回复了问题 • 6 人关注 • 3 个回复 • 1000 次浏览 • 2016-10-24 15:35 • 来自相关话题

panic/recover工作原理

文章分享themoonstone 发表了文章 • 1 个评论 • 649 次浏览 • 2016-10-24 15:09 • 来自相关话题

在Golang里面没有大家所熟悉的try-cache异常机制、而是用panic/recover代替 异常throw / catch和panic / recover是有些类似的,比如、recover的作用是捕获并返回panic提交的错误对象、这可以理解为通... 查看全部

在Golang里面没有大家所熟悉的try-cache异常机制、而是用panic/recover代替
异常throw / catch和panic / recover是有些类似的,比如、recover的作用是捕获并返回panic提交的错误对象、这可以理解为通过调用panic抛出一个值、该值可以通过调用recover函数进行捕获。
主要的区别是,即使当前goroutine处于panic状态,或当前goroutine中存在活动紧急情况,恢复调用仍可能无法检索这些活动紧急情况抛出的值。


For example:


package main

import (
"fmt"
)

func main() {
defer func() {
defer func() {
fmt.Println("6:", recover())
}()
}()
defer func() {
func() {
fmt.Println("5:", recover())
}()
}()
func() {
defer func() {
fmt.Println("1:", recover())
}()
}()
func() {
defer fmt.Println("2:", recover())
}()
func() {
fmt.Println("3:", recover())
}()

fmt.Println("4:", recover())
panic(1)
defer func() {
fmt.Println("0:", recover()) // never go here
}()
}

上述程序中的7个恢复调用都没有恢复程序。 程序崩溃并打印出堆栈跟踪:


$ go run example1.go
1:
2:
3:
4:
5:
6:
panic: 1


goroutine 1 [running]:
...
显然,第0个恢复调用是不可达的。 对于其他recover,让我们先检查Go规范:
如果满足以下任一条件,recover的返回值为nil:



  • 1.panic参数是nil

  • 2.当前goroutine没有产生panic

  • 3.recover不是由延迟函数直接调用。


让我们忽略第一个条件。 第二个条件覆盖第一/第二/第三和第四recover调用。 第三个覆盖第5个recover调用。 然而,三个条件中没有一个覆盖第六个recover调用。
怎样才能让recover调用起作用?如下 :


import("fmt")
func main(){
defer func(){
fmt.Println(recover())// 1
}()
panic(1)
}

现在,panic值被recover调用捕获,并且程序不会崩溃。
那么,使recover调用生效的主要规则是什么?
首先,让我们学习一些概念和说明。


概念:延迟函数调用概念:延迟函数调用


当函数被延迟调用时,或者函数的调用使用defer关键字作为前缀,则调用被称为延迟调用。


package main
func main(){
defer func(){// deferred function calling
func(){// not a deferred function calling
defer recover()// deferred function calling
}()
}()
func(){
// not a deferred function calling
defer func(){
/// deferred function calling
}()
}()
}

概念:函数调用级别和Goroutine执行级别


函数调用级别是指函数调用的深度,与主函数或者goroutine的入口函数相关。


package main

funcmain(){
// level 0
go func(){
// level 0
func(){
// level 1
}()
func(){
// level 1
func(){
// level 2
}()
}()
}()
func(){
// level 1
func(){
// level 2
go func(){
// level 0
}()
}()
go func(){
// level 0
}()
}()
}

goroutine当前执行点的调用级别称为goroutine的执行级别。


说明:panic只能向上传播


是的,panic只能向上传播,沿着函数调用堆栈反向。panic从不通过深入到函数调用中传播。


package main

import"fmt"
func main(){// calling level 0
defer func(){// calling level 1
fmt.Println("Now, the panic is still in calling level 0")
func(){// calling level 2
fmt.Println("Now, the panic is still in calling level 0")
func(){// calling level 3
fmt.Println("Now, the panic is still in calling level 0")
}()
}()
}()
defer fmt.Println("Now, the panic is in calling level 0")
func(){
// calling level 1
defer fmt.Println("Now, the panic is in calling level 1")
func(){// calling level 2
defer fmt.Println("Now, the panic is in calling level 2")
func(){// calling level 3
defer fmt.Println("Now, the panic is in calling level 3")
panic(1)
}()
}()
}()
}

The output:
Now, the panic is in calling level 3


Now, the panic is in calling level 2


Now, the panic is in calling level 1


Now, the panic is in calling level 0


Now, the panic is still in calling level 0


Now, the panic is still in calling level 0


Now, the panic is still in calling level 0


panic: 1


goroutine 1 [running]:


...


概念:panic级别


panic级别意味着panic传播到函数调用的哪一层级、因为panic只能向上传递、所以panic等级永远不加增加、只会减小、在goroutine中,当前panic的水平永远不会大于goroutine的执行水平。


说明:在同一层级上、新的panics会压制原有panics


Example:
package main

import"fmt"
func main(){
defer fmt.Println("program will not crash")
defer func(){
fmt.Println(recover())// 3
}()
defer fmt.Println("now, panic 3 suppresses panic 2")
defer panic(3)
defer fmt.Println("now, panic 2 suppresses panic 1")
defer panic(2)
panic(1)
}

Outputs:


now, panic 2 suppresses panic 1


now, panic 3 suppresses panic 2


3


program will not crash


在以上程序中、我们最终只能看到一个panic 3、panic 3被recover捕获、因此程序不会崩溃
在一个goroutine中,在任何时候在相同的调用级别将有至多一个主动panic。 特别是,当执行点运行在goroutine的调用级别0时,在goroutine中最多只有一个活动的panic。


说明:多个主动panic在一个Goroutine中的共存


Example:


package main

import"fmt"
func main(){// callnig level 0
defer fmt.Println("program will crash, for panic 3 is stll active")
defer func(){// calling level 1
defer func(){// calling level 2
fmt.Println(recover())// 6
}()// the level of panic 3 is 0.// the level of panic 6 is 1.
defer fmt.Println("now, there are two active panics: 3 and 6")
defer panic(6)// will suppress panic 5
defer panic(5)// will suppress panic 4
panic(4)// will not suppress panic 3, for they have differrent levels
// the level of panic 3 is 0.// the level of panic 4 is 1.
}()
defer fmt.Println("now, only panic 3 is active")
defer panic(3)// will suppress panic 2
defer panic(2)// will suppress panic 1
panic(1)
}

在该示例中,panic 6、两个处于active状态中的panic之一被recover捕获。 但是其他panic,panic 3,在主调用结束时仍然活动,所以程序将崩溃。
Outputs:


now, only panic 3 is active


now, there are two active


panics: 3 and 6


6


program will crash, for panic
3 is stll active


panic: 1


panic: 2

panic: 3

goroutine 1 [running]:
...


说明:低级的panics将会被首先捕获


Example:


package main

import"fmt"
func main(){
defer func(){
defer func(){
fmt.Println("panic",recover(),"is recovered")// panic 2 is recovered
}()
defer fmt.Println("panic",recover(),"is recovered")// panic 1 is recovered
defer fmt.Println("now, two active panics coexist")
panic(2)
}()
panic(1)
}

Outputs:


now, two active panics coexist


panic 1 is recovered


panic 2 is recovered


那么,什么是使recover调用生效的主要规则是什么?
规则很简单


在一个goroutine中,如果recover调用的调用函数是F并且F调用的级别是L,则为了使recover调用生效,F调用必须是延迟调用,并且必须存在主动panic的水平为L-1。
相对来说、这是一个比go规格更好的描述、 现在你可以回页面检查为什么第一个例子中的第6个recover调用不会生效了


原文链接:http://www.tapirgames.com/blog/golang-panic-recover-mechanism

讨论一下如何建立一个好的社区氛围?

文章分享linbojin 回复了问题 • 28 人关注 • 27 个回复 • 1351 次浏览 • 2016-10-24 13:41 • 来自相关话题

调研下大家都用golang干嘛

Golangseeyoup 回复了问题 • 11 人关注 • 9 个回复 • 768 次浏览 • 2016-10-24 12:54 • 来自相关话题

上海/ Teambition 30k-40k 寻觅 Go 大牛

招聘应聘SunisDown 回复了问题 • 14 人关注 • 13 个回复 • 3025 次浏览 • 2016-10-24 12:12 • 来自相关话题

已解决:ubuntu下sublime-text3 第三方包没有代码提示

回复

有问必答SoloMagic 发起了问题 • 1 人关注 • 0 个回复 • 524 次浏览 • 2016-10-24 11:31 • 来自相关话题