当 go 遇到“墙”时

转自:https://my.oschina.net/xxbAndy/blog/846722

作为一名从py转向go语言的新手,在使用第三方包的时候我们需要比较熟悉该包或者模块的构建与安装,好比在使用pip或者easy_install之类的工具安装模块时经常会遇到底层库或者工具包的依赖再或者网络超时而导致模块安装失败。然而在使用go的过程中,虽然不必像py那样为一个复杂模块去解决各种的依赖关系,但在使用go get的过程中也不一定一帆风顺,比如你去下载golang.org上的包时,对不起,一般肯定是会被墙掉的。

为何会被墙掉?

&^*(^*%^&*)&*^&*%$%$^&*(*()&*^&%^&()**(%$%&*((^%%^*(*)*)总之,由于某某原因,它和它家的主人google都被墙掉了。

如何解决?

两种方式:第一种无非就是使用vpn技术啦,然后再在本地配个代理啥的,不过既然都是开源的东西,就一定能够从github上面clone下来。所以第二种方式就是就是去从github上面直接clone下来,然后搞成go可以识别的包就可以啦github.com现在肯定是不会被墙啦。 vpn的方式就是搭了个梯子然后配置下代理就可以直接使用go get了,这里主要讲一下第二种方式去安装第三方包。

假设我想使用go语言的docker客户端去封装改造一些东西,通过go get -v可以查看到安装package的详情

$go get -v github.com/fsouza/go-dockerclient

package golang.org/x/net/html: unrecognized import path "golang.org/x/net/html" (https fetch: Get https://golang.org/x/net/html?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
package golang.org/x/net/html/atom: unrecognized import path "golang.org/x/net/html/atom" (https fetch: Get https://golang.org/x/net/html/atom?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

由以上提示可以大概猜得到,本地服务器肯定是无法访问golang.org的,因此在下载golang.org相关的包的时候无法下载导致dockerclient下载失败。

由于go get其实是将package下载下来,然后进行本地安装的,因此我们也可以讲golang.org的相关包clone到本地然后再进行安装。

1.查看配置环境

主要的就是GOPATH和GOROOT

# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/export/test-go"
GORACE=""
GOROOT="/export/go"
GOTOOLDIR="/export/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

注意:所有下载的包都会默认放在GOPATH,因此这个目录是必须的,且一般包含src pkg bin三个目录,分别存放源码包,编译包以及可执行文件

2.下载安装golang.org/x/net

为了使包的导入方式不变,我们需要在src目录下面构造目录结构

$mkdir -p $GOPATH/src/golang.org/x/
$cd $GOPATH/src/golang.org/x/
$git clone https://github.com/golang/net.git net 
$go install net 

执行go install之后没有提示,就说明安装好了。

3.再次安装go的dockerclient

# go get -v  github.com/fsouza/go-dockerclient 
github.com/fsouza/go-dockerclient (download)
github.com/docker/docker (download)
github.com/docker/go-units (download)
github.com/hashicorp/go-cleanhttp (download)
github.com/docker/docker/api/types/network
github.com/docker/docker/pkg/promise
github.com/docker/docker/api/types/blkiodev
github.com/docker/docker/api/types/mount
github.com/docker/docker/api/types/strslice
github.com/docker/docker/vendor/github.com/docker/go-connections/nat
github.com/docker/docker/vendor/github.com/docker/go-units
github.com/docker/docker/api/types/versions
github.com/docker/docker/api/types/registry
github.com/docker/docker/vendor/github.com/Sirupsen/logrus
github.com/docker/docker/vendor/github.com/opencontainers/runc/libcontainer/user
github.com/docker/docker/vendor/golang.org/x/net/context
github.com/docker/docker/vendor/github.com/opencontainers/runc/libcontainer/system
github.com/docker/docker/vendor/github.com/Nvveen/Gotty
github.com/docker/docker/pkg/jsonlog
github.com/docker/docker/pkg/term
github.com/docker/docker/pkg/stdcopy
github.com/docker/go-units
github.com/hashicorp/go-cleanhttp
golang.org/x/net/context
github.com/docker/docker/api/types/filters
github.com/docker/docker/pkg/system
github.com/docker/docker/pkg/ioutils
golang.org/x/net/context/ctxhttp
github.com/docker/docker/api/types/container
github.com/docker/docker/pkg/idtools
github.com/docker/docker/api/types/swarm
github.com/docker/docker/pkg/fileutils
github.com/docker/docker/pkg/pools
github.com/docker/docker/api/types
github.com/docker/docker/pkg/homedir
github.com/docker/docker/pkg/jsonmessage
github.com/docker/docker/pkg/archive
github.com/docker/docker/opts
github.com/fsouza/go-dockerclient

使用-v参数可以查看该包关联的所有包,可以看到已经成功安装

4.测试Docker客户端的使用github.com/fsouza/go-dockerclient

示例:查看当前docker主机上所下载的images

#cat JFdocker.go
package main

import (
	"fmt"
	"github.com/fsouza/go-dockerclient"
	"strings"
)

func main() {
	//定义一个socker文件路径
	endpoint := "unix://var/run/docker.sock"
	//创建一个docker客户端链接
	client, err := docker.NewClient(endpoint)
	//判断是否异常,并且捕获
	if err != nil {
		panic(err)
	}
	//使用创建的client进行listimages操作
	images, err := client.ListImages(docker.ListImagesOptions{All: false})
	if err != nil {
		panic(err)
	}
	//使用range迭代所有images信息
	for _, img := range images {
		fmt.Printf("ID:%v\tTag:%v\t\t Size:%v\t\t VSize:%v\n",
			//image.ID为一个string类型并且以sha215:开头 strings.Split('strings','split')可以将结果分割并且存放在slice中
			strings.Split(img.ID, ":")[1][:12],
			img.RepoTags, img.Size, img.VirtualSize)
	}

}

编译并执行程序:
#go build JFDocker.go
sh-4.2# ./JFDocker 
ID:e740f4a4a24d	Tag:[centos6.8-test-app:v2]		 Size:2411566940		 VSize:2411566940
ID:d5cb0af109de	Tag:[centos6.8-test-app:latest]		 Size:2408322269		 VSize:2408322269
ID:67591570dd29	Tag:[centos:latest]		 Size:191839169		 VSize:191839169

可以看到,现在就可以成功的使用go的docker client进行开发程序了。至此,我们已经成功的解决了go get 无法安装golang.org相关的包了。

展开阅读全文

当cglib遇到单例

06-19

使用cglib产生代理,被代理的是个单例,因此构造函数为私有.但cglib产生代理的时候又需要一个public的的构造函数,因此报错.rn我现在的原则是为了维护单例,构造函数必须为private,寻求可能的方式来使cglib通过并生成我最终的代理..rnrn代码如下:rn[code=java]rnpublic class MyCache rnrn /**rn * Singleton instance of MyCache .rn */rn private static MyCache instance = null;rn rn /**rn * Return the singleton instance of MyCache .rn * @return The singleton instance of MyCache .rn */rn public static MyCache getInstance() rn if (null == instance) rn synchronized (MyCache .class) rn if (null == instance) rn //use cglib to create a proxy,MyCacheProxy is implement by cglib.rn instance = MyCacheProxy.createProxyInstance(MyCache.class);rn rn rn rn rn return instance;rn rn rn // private construcor becuase of singlete..rn private MyCache rn rnrn rn[/code]rnrn现在是cglib不能识别private的构造函数,会报错,改为public就可以正常..rn我的想法是在cglib产生代理前,利用反射把构造函数的modifiers由private改为public,产生代理后再改为private.rn但没有找到相关方法改modifier,只有一个setAccessible(true),但经试验这不能改modifier,报错依旧..rnrnrn请问各位还有其他思路或者按照这个思路的解决方案没有?前提是保持priavte的构造函数,谢谢.!rnrnrnrn----------------------------分割线---------------------------------------rnrn我现在已经在静态方法 MyCacheProxy.createProxyInstance(MyCache.class) 里把MyCache.class这个类的modifier修改为public了,但还是报错,代码如下:rnrn[code=java]rnpublic static T createProxyInstance(Class target) rn T proxyInstance = null;rn rn //change the modifiers of T to public,then switch back.rn Constructor constructor = null;rn Constructor rootConstructor = null;rn rn boolean constructorFlag = false;rn boolean rootConstructorFlag = false;rn rn Field constructorModifiersField = null;rn Field rootConstructorField = null;rn boolean constructorModifiersFieldFlag = false;rn rn int constructorModifiers = Modifier.PRIVATE;rn int rootConstructorModifiers = Modifier.PRIVATE;rn try rn rn //get the target constructor,and set the modifiers from private to public.rn constructor = target.getDeclaredConstructor(null);rn constructorFlag = constructor.isAccessible();rn constructor.setAccessible(true);rn constructorModifiersField = Class.forName("java.lang.reflect.Constructor").getDeclaredField("modifiers");rn constructorModifiersFieldFlag = constructorModifiersField.isAccessible();rn constructorModifiersField.setAccessible(true);rn constructorModifiers = (Integer)constructorModifiersField.get(constructor); rn constructorModifiersField.set(constructor, Modifier.PUBLIC);rnrn //get the root constructor from the target constructor,then set the modifiers from private to public.rn rootConstructorField = Class.forName("java.lang.reflect.Constructor").getDeclaredField("root");rn rootConstructorField.setAccessible(true);rn rootConstructor = (Constructor) rootConstructorField.get(constructor);rn rootConstructorFlag = rootConstructor.isAccessible();rn rootConstructor.setAccessible(true);rn rootConstructorModifiers = (Integer)constructorModifiersField.get(rootConstructor);rn constructorModifiersField.set(rootConstructor, Modifier.PUBLIC);rnrn //use the cglib to create the proxy instancern Enhancer enhancer = new Enhancer();rn enhancer.setSuperclass(target);rn enhancer.setCallback(new TecLazyCacheProxy());rn enhancer.setInterceptDuringConstruction(false);rn proxyInstance = (T) enhancer.create();rn rn catch (SecurityException e) rn e.printStackTrace();rn catch (IllegalArgumentException e) rn e.printStackTrace();rn catch (IllegalAccessException e) rn e.printStackTrace();rn catch (NoSuchFieldException e) rn e.printStackTrace();rn catch (ClassNotFoundException e) rn e.printStackTrace();rn catch (NoSuchMethodException e) rn e.printStackTrace();rn finallyrn //set the accessible and modifiers back when the proxy have been created!rn try rn constructorModifiersField.set(constructor, constructorModifiers);rn constructorModifiersField.set(rootConstructor, rootConstructorModifiers);rn catch (IllegalArgumentException e) rn e.printStackTrace();rn catch (IllegalAccessException e) rn e.printStackTrace();rn rn if (null != constructor) constructor.setAccessible(constructorFlag);rn if (null != rootConstructor) rootConstructor.setAccessible(rootConstructorFlag);rn if (null != constructorModifiersField) constructorModifiersField.setAccessible(constructorModifiersFieldFlag);rn rn rn rn return proxyInstance;rn rn[/code]rnrn不知道我是不是修改漏了什么???rn请问各位还有其他思路或者按照这个思路的解决方案没有?前提是保持priavte的构造函数,谢谢.! 论坛

没有更多推荐了,返回首页