首页 文章 精选 留言 我的

精选列表

搜索[指标分析],共10000篇文章
优秀的个人博客,低调大师

hive的shims相关类分析

在hive的源码中经常可以看到shims相关的类,shims相关类是用来兼容不同的hadoop和hive版本的,以HadoopShims为例org.apache.hadoop.hive.shims.HadoopShims是一个接口,具体的实现类为 1 2 3 org.apache.hadoop.hive.shims.Hadoop20Shims org.apache.hadoop.hive.shims.Hadoop20SShims org.apache.hadoop.hive.shims.Hadoop23Shims 具体对应的那个shims类在ShimLoader类(org.apache.hadoop.hive.shims.ShimLoader)中有所定义,以HADOOP_SHIM_CLASSES为例: 1 2 3 4 5 6 7 8 9 10 /** *ThenamesoftheclassesforshimmingHadoopforeachmajorversion. */ private static final HashMap<String,String>HADOOP_SHIM_CLASSES= new HashMap<String,String>(); //首先定义了一个hashmap static { HADOOP_SHIM_CLASSES.put( "0.20" , "org.apache.hadoop.hive.shims.Hadoop20Shims" ); //0.20 HADOOP_SHIM_CLASSES.put( "0.20S" , "org.apache.hadoop.hive.shims.Hadoop20SShims" ); //1.x和0.20security版本的hadoop HADOOP_SHIM_CLASSES.put( "0.23" , "org.apache.hadoop.hive.shims.Hadoop23Shims" ); //2.x版本的hadoop } //向hashmap中插入对应的项,key为version信息,value为实际对应的类 ShimLoader类通过getHadoopShims方法返回具体的HadoopShims 1 2 3 4 5 6 7 8 private static HadoopShimshadoopShims; ...... public static synchronized HadoopShimsgetHadoopShims(){ if (hadoopShims== null ){ hadoopShims=loadShims(HADOOP_SHIM_CLASSES,HadoopShims. class ); //调用loadShims方法 } return hadoopShims; } 而loadShims方法通过判断hadoop的版本,来获取hashmap中对应的设置类 1 2 3 4 5 private static <T>TloadShims(Map<String,String>classMap,Class<T>xface){ Stringvers=getMajorVersion(); //获取hadoop的版本 StringclassName=classMap.get(vers); return createShim(className,xface); } 具体哪个hadoop版本是由getMajorVersion获取,比如我们线上使用的是2.0.0-cdh4.6.0,那么getMajorVersion返回的值为0.23,对应的HadoopShims实现类为org.apache.hadoop.hive.shims.Hadoop23Shims 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public static StringgetMajorVersion(){ Stringvers=VersionInfo.getVersion(); //org.apache.hadoop.util.VersionInfo类的getVersion方法比如2.0.0-cdh4.6.0 String[]parts=vers.split( "\\." ); if (parts.length< 2 ){ throw new RuntimeException( "IllegalHadoopVersion:" +vers+ "(expectedA.B.*format)" ); } //SpecialhandlingforHadoop1.xand2.x switch (Integer.parseInt(parts[ 0 ])){ case 0 : break ; case 1 : return "0.20S" ; case 2 : return "0.23" ; default : throw new IllegalArgumentException( "UnrecognizedHadoopmajorversionnumber:" +vers); } StringmajorVersion=parts[ 0 ]+ "." +parts[ 1 ]; //Ifwearerunningasecurityrelease,wewon'thaveUnixUserGroupInformation //(removedbyHADOOP-6299whenswitchingtoJAASforLogin) try { Class.forName( "org.apache.hadoop.security.UnixUserGroupInformation" ); } catch (ClassNotFoundExceptioncnf){ if ( "0.20" .equals(majorVersion)){ majorVersion+= "S" ; } } return majorVersion; } 而不同的shims中规定了不同版本下的属性和方法等,比如判断是否localmode: 1).Hadoop20SShims类(Hadoop0.20 with Security和1.x版本) 1 2 3 4 5 6 7 8 @Override public boolean isLocalMode(Configurationconf){ return "local" .equals(getJobLauncherRpcAddress(conf)); } @Override public StringgetJobLauncherRpcAddress(Configurationconf){ //通过判断mapred.job.tracker的设置 return conf.get( "mapred.job.tracker" ); } 2).Hadoop20Shims类(Hadoop0.20版本) 同上3).Hadoop23Shims(Hadoop2.x版本) 1 2 3 4 @Override public boolean isLocalMode(Configurationconf){ return "local" .equals(conf.get( "mapreduce.framework.name" )); //根据mapreduce.framework.name设置 } 本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1564601,如需转载请自行联系原作者

优秀的个人博客,低调大师

docker1.12-containerd源码分析

从原openstack转型至docker已有一段时间。更稳定的使用docker了解docker的各流程,从源代码层面了解下containerd。本文基于docker 1.12版本,从1.11开始docker已拆分docker daemon containerd源码流程图 源码接口调用详情 A)第一步从ctr入口至API接口 checkpoint(用于快照,docker目前该功能不完善) 1 2 3 list--> /types .API /ListCheckpoint create--> /types .API /CreateCheckpoint delete--> /types .API /DeleteCheckpoint containers 1 2 3 4 5 6 7 8 9 list、state--> /types .API /State pause、resume、update--> /types .API /UpdateContainer create--> /types .API /CreateContainer stats--> /types .API /Stats watch --> /types .API /State 、 /types .API /Events exec --> /types .API /Events 、 /types .API /AddProcess 、 /types .API /UpdateProcess kill --> /types .API /Signal start--> /types .API /Events 、 /types .API /CreateContainer 、 /types .API /UpdateProcess update--> /types .API /UpdateContainer events 1 /types .API /Events state 1 /types .API /State version 1 /types .API /GetServerVersion -- return result B)第二步从API接口至supervisor任务处理 1 注:API--server.go-->daemon–supervisor.go(handleTaskfunc) checkpoint 1 2 3 /types .API /ListCheckpoint (supervisor.GetContainersTask)-->getContainers /types .API /CreateCheckpoint -->createCheckpoint /types .API /DeleteCheckpoint -->deleteCheckpoint containers 1 2 3 4 5 6 7 /types .API /State /types .API /Stats (supervisor.GetContainersTask)-->getContainers /types .API /UpdateContainer (supervisor.UpdateTask)-->updateContainer /types .API /CreateContainer (supervisor.StartTask)-->start /types .API /Events -->Events-- return result /types .API /AddProcess -->addProcess /types .API /UpdateProcess -->updateProcess /types .API /Signal -->signal C)第三步从任务队列至runtime至runc checkpoint 1 2 3 getContainers-- return result createCheckpoint-->(runtime)CheckPoint--> exec .Command(c.runtime,arg....) deleteCheckpoint-->(runtime)DeleteCheckpoint-- return result containers 1 2 3 4 5 6 getContainers-- return result updateContainer-->(runtime)ResumePauseUpdateResources--> exec .Command(c.runtime,arg....) start-->(runtimesupervisor /worker .go)Start--> exec .Command(c.shim,c. id ,c.bundle,c.runtime) addProcess-->(runtime) exec --> exec .Command(c.shim,c. id ,c.bundle,c.runtime) updateProcess--> return result signal--> return result createContainer示例 deamon启动监听tasks及startTasks进程 a)进入main.go main方法调用daemon方法 1 2 3 4 5 6 7 app.Action=func(context*cli.Context){ if err:=daemon(context);err!=nil{ logrus.Fatal(err) } } b)进入main.go daemon方法 1 2 3 4 5 6 7 8 for i:=0;i<10;i++{ wg.Add(1) w:=supervisor.NewWorker(sv,wg) gow.Start() } if err:=sv.Start();err!=nil{ return err } c)初始化supervisor/worker.go NewWorker并启动监听startTask并处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 funcNewWorker(s*Supervisor,wg* sync .WaitGroup)Worker{ return &worker{ s:s, wg:wg, } } func(w*worker)Start(){ deferw.wg.Done() for t:=rangew.s.startTasks{ started:= time .Now() process,err:=t.Container.Start(t.CheckpointPath,runtime.NewStdio(t.Stdin,t.Stdout,t.Stderr)) if err!=nil{ logrus.WithFields(logrus.Fields{ "error" :err, "id" :t.Container.ID(), }).Error( "containerd:startcontainer" ) t.Err<-err evt:=&DeleteTask{ ID:t.Container.ID(), NoEvent: true , Process:process, } w.s.SendTask(evt) continue } d)启动supervisor/supervisor.go task监听task并处理 1 2 3 4 5 6 7 8 9 10 11 12 13 func(s*Supervisor)Start()error{ logrus.WithFields(logrus.Fields{ "stateDir" :s.stateDir, "runtime" :s.runtime, "runtimeArgs" :s.runtimeArgs, "memory" :s.machine.Memory, "cpus" :s.machine.Cpus, }).Debug( "containerd:supervisorrunning" ) gofunc(){ for i:=ranges.tasks{ s.handleTask(i) } containers容器创建示例 Ctl控制台命令入口 ctr/main.go containersCommand 1 2 3 4 5 6 7 8 9 10 11 execCommand, killCommand, listCommand, pauseCommand, resumeCommand, startCommand, stateCommand, statsCommand, watchCommand, updateCommand, ctr/container.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 varstartCommand=cli.Command{ Name: "start" , Usage: "startacontainer" , ArgsUsage:"IDBundlePath”,————…... events,err:=c.Events(netcontext.Background(),&types.EventsRequest{})/*事件创建*/ if err!=nil{ fatal(err.Error(),1) } if _,err:=c.CreateContainer(netcontext.Background(),r);err!=nil{/*容器创建*/ fatal(err.Error(),1) } if context.Bool( "attach" ){ gofunc(){ io.Copy(stdin,os.Stdin) if _,err:=c.UpdateProcess(netcontext.Background(),&types.UpdateProcessRequest{/*更新进程*/ Id: id , Pid: "init" , CloseStdin: true , });err!=nil{ fatal(err.Error(),1) } restoreAndCloseStdin() }() if tty { resize( id , "init" ,c) gofunc(){ s:= make (chanos.Signal,64) signal.Notify(s,syscall.SIGWINCH) for ranges{ if err:=resize( id , "init" ,c);err!=nil{ log.Println(err) } } }() } waitForExit(c,events, id , "init" ,restoreAndCloseStdin) } }, api处理 api/grpc/types/api.pb.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 func(c*aPIClient)Events(ctxcontext.Context, in *EventsRequest,opts...grpc.CallOption)(API_EventsClient,error){ stream,err:=grpc.NewClientStream(ctx,&_API_serviceDesc.Streams[0],c.cc, "/types.API/Events" ,opts...) if err!=nil{ return nil,err } x:=&aPIEventsClient{stream} if err:=x.ClientStream.SendMsg( in );err!=nil{ return nil,err } if err:=x.ClientStream.CloseSend();err!=nil{ return nil,err } return x,nil } func(c*aPIClient)CreateContainer(ctxcontext.Context, in *CreateContainerRequest,opts...grpc.CallOption)(*CreateContainerResponse,error){ out:=new(CreateContainerResponse) err:=grpc.Invoke(ctx, "/types.API/CreateContainer" , in ,out,c.cc,opts...) if err!=nil{ return nil,err } return out,nil } func(c*aPIClient)UpdateProcess(ctxcontext.Context, in *UpdateProcessRequest,opts...grpc.CallOption)(*UpdateProcessResponse,error){ out:=new(UpdateProcessResponse) err:=grpc.Invoke(ctx, "/types.API/UpdateProcess" , in ,out,c.cc,opts...) if err!=nil{ return nil,err } return out,nil } api/grpc/types/api.pb.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 func_API_Events_Handler(srvinterface{},streamgrpc.ServerStream)error{ m:=new(EventsRequest) if err:=stream.RecvMsg(m);err!=nil{ return err } return srv.(APIServer).Events(m,&aPIEventsServer{stream}) } func_API_CreateContainer_Handler(srvinterface{},ctxcontext.Context,decfunc(interface{})error,interceptorgrpc.UnaryServerInterceptor)(interface{},error){ in :=new(CreateContainerRequest) if err:=dec( in );err!=nil{ return nil,err } if interceptor==nil{ return srv.(APIServer).CreateContainer(ctx, in ) } info:=&grpc.UnaryServerInfo{ Server:srv, FullMethod: "/types.API/CreateContainer" , } handler:=func(ctxcontext.Context,reqinterface{})(interface{},error){ return srv.(APIServer).CreateContainer(ctx,req.(*CreateContainerRequest)) } return interceptor(ctx, in ,info,handler) } func_API_UpdateProcess_Handler(srvinterface{},ctxcontext.Context,decfunc(interface{})error,interceptorgrpc.UnaryServerInterceptor)(interface{},error){ in :=new(UpdateProcessRequest) if err:=dec( in );err!=nil{ return nil,err } if interceptor==nil{ return srv.(APIServer).UpdateProcess(ctx, in ) } info:=&grpc.UnaryServerInfo{ Server:srv, FullMethod: "/types.API/UpdateProcess" , } handler:=func(ctxcontext.Context,reqinterface{})(interface{},error){ return srv.(APIServer).UpdateProcess(ctx,req.(*UpdateProcessRequest)) } return interceptor(ctx, in ,info,handler) api/grpc/server/server.go进入第一步中的tasks及sendTasks处理队列 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 func(s*apiServer)Events(r*types.EventsRequest,streamtypes.API_EventsServer)error{ events:=s.sv.Events(t,r.StoredOnly,r.Id) func(s*apiServer)CreateContainer(ctxcontext.Context,c*types.CreateContainerRequest)(*types.CreateContainerResponse,error){ s.sv.SendTask(e) apiC,err:=createAPIContainer(r.Container, false ) func(s*apiServer)UpdateProcess(ctxcontext.Context,r*types.UpdateProcessRequest)(*types.UpdateProcessResponse,error){ e:=&supervisor.UpdateProcessTask{} e.ID=r.Id e.PID=r.Pid e.Height=int(r.Height) e.Width=int(r.Width) e.CloseStdin=r.CloseStdin s.sv.SendTask(e) if err:=<-e.ErrorCh();err!=nil{ return nil,err } return &types.UpdateProcessResponse{},nil } supervisor/create.go 1 2 func(s*Supervisor)start(t*StartTask)error{ s.startTasks<-task supervisor/worker.go 1 2 3 func(w*worker)Start(){ deferw.wg.Done() for t:=rangew.s.startTasks{ runtime/container.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 func(c*container)Start(checkpointPathstring,sStdio)(Process,error){ processRoot:=filepath.Join(c.root,c. id ,InitProcessID) if err:=os.Mkdir(processRoot,0755);err!=nil{ return nil,err } cmd:= exec .Command(c.shim, c. id ,c.bundle,c.runtime, )---执行docker-containerd-shim命令 cmd.Dir=processRoot cmd.SysProcAttr=&syscall.SysProcAttr{ Setpgid: true , } spec,err:=c.readSpec() if err!=nil{ return nil,err } config:=&processConfig{ checkpoint:checkpointPath, root:processRoot, id :InitProcessID, c:c, stdio:s, spec:spec, processSpec:specs.ProcessSpec(spec.Process), } p,err:=newProcess(config) if err!=nil{ return nil,err } if err:=c.createCmd(InitProcessID,cmd,p);err!=nil{ return nil,err } return p,nil } containerd-shim接收后处理 containerd-shim/main.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 funcstart(log*os.File)error{ p,err:=newProcess(flag.Arg(0),flag.Arg(1),flag.Arg(2)) if err!=nil{ return err } deferfunc(){ if err:=p.Close();err!=nil{ writeMessage(log, "warn" ,err) } }() if err:=p.create();err!=nil{ p.delete() return err } containerd-shim/process.go跳转执行runc命令 1 2 3 func(p*process)create()error{ cmd:= exec .Command(p.runtime,args...) 本文转自 qwjhq 51CTO博客,原文链接:http://blog.51cto.com/bingdian/1893470

优秀的个人博客,低调大师

ELK日志分析平台搭建全程

环境: OS:Centos 6.6 elasticsearch-5.6.3.tar.gz jdk-8u151-linux-x64.tar.gz kibana-5.6.3-linux-x86_64.tar.gz logstash-5.6.3.tar.gz node-v6.11.4-linux-x64.tar.xz 一、准备环境: 1、创建用户,并给安装目录设置权限 1 2 3 4 [root@1inux~]#groupaddelk [root@1inux~]#useradd-gelkelk [root@1inux~]#mkdir/elk [root@1inux~]#chown-Relk:elk/elk 修改系统某些参数值:【如不修改启动时会报错】 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@1inux~]#vim/etc/security/limits.conf //添加一下内容 --------------------------- *softnofile 65536 *hardnofile 65536 *softnproc 2048 *hardnproc 4096 ---------------------------- [root@bogonelk]#vim/etc/security/limits.d/ 90 -nproc.conf //添加如下内容 *softnproc 2048 [root@1inux~]#vim/etc/sysctl.conf //添加以下内容 ------------------ fs.file- max = 65536 vm.max_map_count= 655360 ---------------------- [root@1inux~]#sysctl-p //查看vm.max_map_count值是否修改成功 修改进程数: [root@1inux~]#ulimit-u 2048 安装Java [root@1inux elk]# mkdir /usr/local/Java [root@1inux elk]# tar -zxvf jdk-8u151-linux-x64.tar.gz -C /usr/local/Java 添加环境变量: [root@1inux jdk1.8.0_151]# vim /etc/profile 添加如下: 1 2 3 exportJAVA_HOME=/usr/local/Java/jdk1.8.0_151 exportPATH=$PATH:$JAVA_HOME/bin exportCLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPAT 重新加载 [root@1inux jdk1.8.0_151]# source /etc/profile 查看是否安装成功: 1 2 3 4 [root@1inuxjdk1 .8. 0_151]#java-version javaversion" 1.8. 0_151" Java(TM)SERuntimeEnvironment(build 1.8. 0_151-b12) JavaHotSpot(TM) 64 -BitServerVM(build 25.151 -b12,mixedmode) 二:安装ELK 1、安装elasticsearch 1 2 3 4 5 6 #tar-zxvfelasticsearch-5.6.3.tar.gz 修改配置文件: vim./elasticsearch-5.6.3/config/elasticsearch.yml //设置监听IP及监听端口: network.host:0.0.0.0//设置监听IP http.port:9200//设置监听端口 注:elasticsearch不能使用root用户启动 启动elasticsearch//第一次启动有点慢: 1 2 3 4 5 6 7 [elk@1inuxroot]$cd/elk/elasticsearch-5.6.3/bin [elk@1inuxbin]$./elasticsearch 然后查看端口: [root@1inux~]#ss-tnl|grep9200 LISTEN0128::ffff:192.168.159.130:9200:::* [root@1inux~]# 1.1安装部署head 编辑elasticsearch配置文件做如下修改: 1 2 3 4 5 6 #vim/elk/elasticsearch-5.6.3/config/elasticsearch.yml node.name:node-1inux//修改集群名字 cluster.name:my-1inux//修改节点名字 //增加新的参数,这样head插件可以访问es http.cors.enabled:true http.cors.allow-origin: "*" 1)安装git 1 [root@ 1 inux/]#yum-yinstallgit 下载代码: 1 [root@ 1 inuxelk]#gitclonegit://github.com/mobz/elasticsearch-head.git 修改head目录权限: 1 [root@1inuxelk]#chown-Relk:elkelasticsearch-head 2)下载安装node https://nodejs.org/en/download/ 然后下载xz进行解压 1 2 3 #yum-yinstallxz [root@1inuxelk]#xz-dnode-v6.11.4-linux-x64.tar.xz [root@1inuxelk]#tar-xvfnode-v6.11.4-linux-x64.tar 添加node的环境变量 1 2 3 4 5 6 7 [root@ 1 inuxnode-v 6.11 . 4 -linux-x 64 ]#vim/etc/profile 添加如下: exportNODE_HOME=/elk/node-v 6.11 . 4 -linux-x 64 exportPATH=$PATH:$NODE_HOME/bin 重新加载 [root@ 1 inuxnode-v 6.11 . 4 -linux-x 64 ]#source/etc/profile 查看是否生效: 1 2 3 4 5 6 [root@1inuxnode-v6.11.4-linux-x64]#echo$NODE_HOME /elk/node-v6.11.4-linux-x64 [root@1inuxnode-v6.11.4-linux-x64]#node-v v6.11.4 [root@1inuxnode-v6.11.4-linux-x64]#npm-v 3.10.10 1 2 3 切换国内镜像源: npmconfig set registryhttps: //registry.npm.taobao.org npmconfig set disturlhttps: //npm.taobao.org/dist 3)安装grunt 1 2 [root@1inuxnode_modules]#npminstall-ggrunt [root@1inuxnode-v6.11.4-linux-x64]#npminstallgrunt-cli-g 查看是否安装成功: 1 2 [root@1inuxnode-v6 .11.4 -linux-x64]#grunt-version grunt-cliv1 .2.0 修改服务器监听地址 1 2 [root@1inuxelk]#vim/elk/elasticsearch-head/Gruntfile.js hostname:'*', 修改链接地址: 1 2 3 4 [root@1inuxelk]#vim/elk/elasticsearch-head/_site/app.js this .base_uri= this .config.base_uri|| this .prefs.get( "app-base_uri" )||" 修改为: this .base_uri= this .config.base_uri|| this .prefs.get( "app-base_uri" )|| "http://192.168.159.130:9200" ; 运行head 1 2 3 4 在head目录中执行 [root@1inuxelasticsearch-head]#npminstall 启动: [root@1inuxelasticsearch-head]#gruntserver 2、安装kibana [root@1inux elk]# tar -zxvf kibana-5.6.3-linux-x86_64.tar.gz 1 2 3 4 5 6 7 解压后编辑配置文件; [root@ 1 inuxbin]#vim../config/kibana.yml//修改为elasticsearch的访问地址及端口如下 #server.host: "localhost" server.host: "192.168.159.130" #elasticsearch.url: "http://localhost:9200" elasticsearch.url:" 然后保存启动如下; 1 2 3 4 5 6 7 8 [root@1inuxbin]#./kibana log [15:45:26.952][info][status][plugin:kibana@5.6.3]Statuschangedfromuninitializedtogreen-Ready log [15:45:27.067][info][status][plugin:elasticsearch@5.6.3]Statuschangedfromuninitializedtoyellow-WaitingforElasticsearch log [15:45:27.118][info][status][plugin:console@5.6.3]Statuschangedfromuninitializedtogreen-Ready log [15:45:27.136][info][status][plugin:metrics@5.6.3]Statuschangedfromuninitializedtogreen-Ready log [15:45:27.566][info][status][plugin:timelion@5.6.3]Statuschangedfromuninitializedtogreen-Ready log [15:45:27.697][info][listening]Serverrunningathttp://localhost:5601 log [15:45:27.699][info][status][uisettings]Statuschangedfromuninitializedtoyellow-Elasticsearchpluginisyellow 3、安装logstash-5.6.3.tar.gz 1 2 3 [root@ 1 inuxelk]#tar-zxvflogstash -5.6 . 3 .tar.gz 解压后编辑配置文件,然后就可以使用了 编写文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 编辑文件#vim/config/test.conf input{ file{ type=> "nginx_log" path=> "/var/log/nginx/access.log" start_position=> "beginning" } } output{ elasticsearch{ hosts=> "192.168.159.130" index=> "1inux" } stdout{codec=>rubydebug} } 启动: root@1inuxbin]#./logstash-f../config/test.conf 报错: 1、 1 2 3 [root@bogonelk]#./elasticsearch- 5.6.3 /bin/elasticsearch [ 2017 - 10 -25T06: 29 : 04 , 996 ][WARN][o . e . b . ElasticsearchUncaughtExceptionHandler][]uncaughtexception in thread[main] org . elasticsearch . bootstrap . StartupException:java . lang . RuntimeException:can not runelasticsearch as root 解决方案:使用elk用户启动 问题二、 1 2 3 4 5 6 ERROR:[4]bootstrapchecksfailed [1]:maxfiledescriptors[4096] for elasticsearchprocess is toolow,increasetoatleast[65536] [2]:maxnumberofthreads[1024] for user[elk] is toolow,increasetoatleast[2048] [3]:max virtual memoryareasvm.max_map_count[65530] is toolow,increasetoatleast[262144] 参考上面系统修改 问题三、 1 2 3 4 编辑elasticsearch配置文件 [ 4 ]:systemcallfiltersfailedtoinstall;checkthelogsandfixyourconfigurationordisablesystemcallfiltersatyourownrisk 在bootstrap.memory_lock下面添加: bootstrap.system_call_filter:false 本文转自 1inux 51CTO博客,原文链接:http://blog.51cto.com/1inux/1976229

优秀的个人博客,低调大师

Java反编译代码分析(一)

浅析如何读懂这种反编译过来的文件,不喜勿喷。 赋值 Node node; Node node1 = _$3.getChildNodes().item(0); node1; node1; JVM INSTR swap ; node; getChildNodes(); 0; item(); getChildNodes(); 0; item(); getNodeValue(); String s; s; 原始语句: Node node; Node node1 = currDocument.getChildNodes().item(0); node = node1; String s = node.getChildNodes().item(0).getChildNodes().item(0).getNodeValue(); //赋值语句 // JVM INSTR swap ; 不带参数创建对象 JVM INSTR new #244 <Class CrossTable>; JVM INSTR dup ; JVM INSTR swap ; CrossTable(); CrossTable crosstable; crosstable; CrossTable crosstable = new CrossTable(); 带参数创建对象 JVM INSTR new #262 <Class StringBuffer>; JVM INSTR dup ; JVM INSTR swap ; String.valueOf(s2); StringBuffer(); s.substring(j, i); append(); s6; append(); toString(); s2; s2 = (new StringBuffer(String.valueOf(s2))).append(s.substring(j, i)).append(s6).toString(); //s2 += s.substring(j, i) + s6; for循环 int k = 0; goto _L4 _L8: ... k++; _L4: if(k < as.length) goto _L8; else goto _L7 for(int k=0;k < as.length;k++) { ... } while循环 String s1 = ""; goto _L1 _L3: JVM INSTR new #262 <Class StringBuffer>; JVM INSTR dup ; JVM INSTR swap ; String.valueOf(s1); StringBuffer(); _$2(resultset, s, l); append(); toString(); s1; _L1: if(resultset.next()) goto _L3; else goto _L2 String s1 = ""; while(resultset.next()) { s1 = s1 + resultSetToString(resultset, s, l); } 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4314546.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

农业物联网应用发展分析

中国农业面临到从农劳力老化以及进口农产品的问题。农业惟一个国家产业的重要基础,因此如何发展农业为中国重要的议题。目前物联网的导入将可以改变这个现象。农业物联网跟传统的生产方式存在着大不同,它可以很方便的实现对用户对农作物生长现场环境进行全方位监测、管理与控制,对建设现代化高水平智能农业生产方式有着重要意义。 农业物联网的应用可以透过多种不同的传感器侦测环境状况,环境状况包含温度、湿度、亮度、土壤湿度、二氧化碳浓度等数据,而随着传感器领域的发展将可以感测出更多元的数据。 在农业生产过程中,通过无线智能传感器实现农业生产现场环境参数的实时采集和利用智能物联网监控系统对所采集数据进行实时传送,为农作物生产和温室控制提供了有利的科学依据。智慧农业不仅为作物生长创造了最佳条件,提高了作物产量和质量,而且可以提高水、化肥等作物消耗品的利用率。 以物联网为基础的自动化农业设备有别于传统农业自动化设备,其所有设备的运作都是根据感测的资料而来,而更进一步的应用将可以侦测到环境或水源是否有重金属或是其他的污染借以解决目前中国的食品安全危机。 以物联网自动化系统为基础的农业将可以减少劳动的付出、其精确自动化的机制将可以减少成本并且可以产出安全以及高质量的农产品。同时通过软硬件系统和手机客户端还能够实现自然灾害监测及预警,方便作物生长现场管理,实现高度的信息共享。 在农产品和食品运输领域,电子标签、电子条码、无线传感器网络、通信网络和计算机网络等的集成应用,可实现单个或集装农产品和食品的跟踪和可视数字化管理,对农产品从生产现场到仓库、从仓库到餐桌、从生产到销售全过程实行智能监控,可实现农产品和食品的数字化、可视化物流运输和管理,同时也可很大程度提高农产品和食品的品质。 航大物联(www.leadtorch.com)智慧农业解决方案包括智能养殖、大田农业、水肥一体化等技术,能够实时提供农业生产各项主要参数,还可以远程操控管理,并轻松实现农业生产的精细化管理,提高农业生产效率。

优秀的个人博客,低调大师

WebView 缓存原理分析和应用

一、背景 现在的App开发,或多或少都会用到Hybrid模式,到了WebView这边,经常会加载一些js文件(例如和WebView用来Native通信的bridge.js),而这些js文件不会经常发生变化,所以我们希望js在WebView里面加载一次之后,如果js没有发生变化,下次就不用再发起网络请求去加载,从而减少流量和资源的占用。那么有什么方式可以达到这个目的呢?先得从WebView的缓存原理入手。二、WebView的缓存类型WebView主要包括两类缓存,一类是浏览器自带的网页数据缓存,这是所有的浏览器都支持的、由HTTP协议定义的缓存;另一类是H5缓存,这是由web页面的开发者设置的,H5缓存主要包括了App Cache、DOM Storage、Local Storage、Web SQL Database 存储机制等,这里我们主要介绍App Cache来缓存js文件。三、浏览器自带的网页数据缓存1.工作原理浏览器缓存机制是通过HTTP协议Header里的Cache-Control(或Expires)和Last-Modified(或 Etag)等字段来控制文件缓存的机制。关于这几个字段的作用和浏览器的缓存更新机制,大家可以看看这两篇文章(H5 缓存机制浅析 移动端 Web 加载性能优化,Android:手把手教你构建 WebView 的缓存机制 & 资源预加载方案),里面有详细的介绍。下面从我实际应用的角度,介绍一下通常会在HTTP协议中遇到的Header。这两个字段是接收响应时,浏览器决定文件是否需要被缓存;或者需要加载文件时,浏览器决定是否需要发出请求的字段。Cache-Control:max-age=315360000,这表示缓存时长为315360000秒。如果315360000秒内需要再次请求这个文件,那么浏览器不会发出请求,直接使用本地的缓存的文件。这是HTTP/1.1标准中的字段。Expires: Thu, 31 Dec 2037 23:55:55 GMT,这表示这个文件的过期时间是2037年12月31日晚上23点55分55秒,在这个时间之前浏览器都不会再次发出请求去获取这个文件。这是HTTP/1.0中的字段,如果客户端和服务器时间不同步会导致缓存出现问题,因此才有了上面的Cache-Control,当它们同时出现在HTTP Response的Header中时,Cache-Control优先级更高。下面两个字段是发起请求时,服务器决定文件是否需要更新的字段。Last-Modified:Wed, 28 Sep 2016 09:24:35 GMT,这表示这个文件最后的修改时间是2016年9月28日9点24分35秒。这个字段对于浏览器来说,会在下次请求的时候,作为Request Header的If-Modified-Since字段带上。例如浏览器缓存的文件已经超过了Cache-Control(或者Expires),那么需要加载这个文件时,就会发出请求,请求的Header有一个字段为If-Modified-Since:Wed, 28 Sep 2016 09:24:35 GMT,服务器接收到请求后,会把文件的Last-Modified时间和这个时间对比,如果时间没变,那么浏览器将返回304 Not Modified给浏览器,且content-length肯定是0个字节。如果时间有变化,那么服务器会返回200 OK,并返回相应的内容给浏览器。ETag:”57eb8c5c-129”,这是文件的特征串。功能同上面的Last-Modified是一样的。只是在浏览器下次请求时,ETag是作为Request Header中的If-None-Match:"57eb8c5c-129"字段传到服务器。服务器和最新的文件特征串对比,如果相同那么返回304 Not Modified,不同则返回200 OK。当ETag和Last-Modified同时出现时,任何一个字段只要生效了,就认为文件是没有更新的。2.WebView如何设置才能支持上面的协议由上面的介绍可知,只要是个主流的、合格的浏览器,都应该能够支持HTTP协议层面的这几个字段。这不是我们开发者可以修改的,也不是我们应该修改的配置。在Android上,我们的WebView也支持这几个字段。但是我们可以通过代码去设置WebView的Cache Mode,而使得协议生效或者无效。WebView有下面几个Cache Mode:LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据。LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。LOAD_CACHE_NORMAL: API level 17中已经废弃,从API level 11开始作用同LOAD_DEFAULT模式LOAD_NO_CACHE: 不使用缓存,只从网络获取数据。LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。本地没有缓存时才从网络上获取。设置WebView缓存的Cache Mode示例代码如下:WebSettings settings = webView.getSettings(); settings.setCacheMode(WebSettings.LOAD_DEFAULT); 网上很多人都说根据网络条件去选择Cache Mode,当有网络时,设置为LOAD_DEFAULT,当没有网络时设置为LOAD_CACHE_ELSE_NETWORK。但是在我的业务中,js文件的更新都是非覆盖式的更新,也就是时候每次改变js文件的时候,文件的url地址一定会发生变化,所以我希望浏览器能够缓存下来js,并且一直使用它,那么我就给它只设置为LOAD_CACHE_ELSE_NETWORK。当然如果你要是可以改js的cdn服务器的Cache-Control字段,那也行啊,用LOAD_DEFAULT就ok了。至于文件是应该采用覆盖式or非覆盖式的更新,不是我今天要讨论的内容,在web前端领域,这是一个可以聊聊的topic。关于iOS的WebView,我同事在实际测试的时候竟然发现,控制文件缓存的Response Header是Expires字段。。而且iOS无法针对整个WebView设置Cache Mode,只能针对每一个URLRequest去设置。。后续有机会要学习一下iOS那块的情况。3.在手机里面的存储路径浏览器默认缓存下来的文件是怎么被存储到了哪里呢?这个问题在接触到WebView以来,就一直是一个谜题。这次由于工作的需要,我特意root了两台手机,一台红米1(Android 4.4)和一台小米4c(Android 5.1),在root高系统版本(6.0和7.1)的两台Nexus都以失败告终之后,我决定还是先看看4.4和5.1系统上,WebView自带的缓存存到了哪里。首先,不用思考就知道,这些文件一定是在/data/data/包名/目录下,在我之前的一篇博客里面提到过,这是每一个应用自己的内部存储目录。接着,我们打开终端,使用adb连接手机,然后按照下面命令操作一下。// 1.先进入shell adb shell // 2.开启root账号 su // 3.修改文件夹权限 chmod 777 data/data/你的应用包名/ // 4.修改子文件夹的权限,因为Android命令行不支持向Linux那样的-R命令实现递归式的chmod。。。 chmod 777 data/data/你的应用包名/* // 5.所以如果你对应用目录层级更深,你就要进一步地chmod。。。 chmod 777 data/data/你的应用包名// // 6.直到终端里提示你说,no such file or directory时,说明chmod完了,所有的内部存储里面的文件夹和文件都可以看到了,如果大家有更好的方法请一定告诉我,多谢了~ Android 4.4的目录:/data/data/包名/app_webview/cache/,如下图所示的第二个文件夹。 可能你注意到了,第一个文件夹是叫Application Cache,我们后面再说它。Android 5.1的目录:/data/data/包名/cache/org.chromium.android_webview/下面,如下图所示。 但是在5.1系统上,/data/data/包名/app_webview/文件夹依然存在,只是4.4系统上面存储WebView自带缓存的app_webview/cache文件夹不再存在了(注意下App Cache目录还在),如下图所示。 综上所述,WebView自带的浏览器协议支持的缓存,在不同的系统版本上,位置是不一样的。也许除了我root过的4.4、5.1以外,其他版本系统的WebView自带缓存还可能存在于不同的目录里面。另外一个是关于缓存文件的存储格式和索引格式,在不同的手机上可能也有差别,因为之前看到网上的人都说有叫webview.db或者webviewCache.db的文件,这个文件呢,还不是在app_webview/cache或者org.chromium.android_webview下面,而是在/data/data/包名/database/里面。但是,我这两台root过的手机都没有看到这种文件,而且我把/data/data/包名/下面所有的db文件都打开看了,并没有发现有存储url记录的table。。实际上,以5.1系统为例,我看到了/data/data/包名/cache/org.chromium.android_webview/下面有叫index和/index-dir/the-real-index的文件,以及一堆名称为md5+下划线+数字的文件,上面的图中也可以看得到,这块的原理仍然有些疑问,也希望专业的大神可以解答一下。四、H5的缓存讲完了WebView自带的缓存,下面讲一下H5里面的App Cache。这个Cache是由开发Web页面的开发者控制的,而不是由Native去控制的,但是Native里面的WebView也需要我们做一下设置才能支持H5的这个特性。1.工作原理写Web页面代码时,指定manifest属性即可让页面使用App Cache。通常html页面代码会这么写: manifest="xxx.appcache">

优秀的个人博客,低调大师

Docker数据安全隐患分析

Docker容器为应用的编写、分发和部署带来真正翻天覆地的变化。容器的目的是灵活性,让应用可按需启用,无论何时以及何地。当然无论我们在哪里使用应用,我们都需要数据。 对于数据应该如何映射到容器主要有两个流派。第一个流派称我们将数据保留在容器中;第二个称我们在容器外保存永久性数据,这些数据可超越任何单个容器的使用寿命。在这两种情况下,安全问题给数据和容器管理带来大问题。 ▲Image: Pexels/Pixabay 管理数据访问 现在有很多技术可用于分配存储到Docker容器。临时存储容量,本地到运行容器的主机,可在运行时分配到容器。存储卷存储在映射到应用的特定子目录的主机内。卷可在容器实例化时创建,或者使用“docker volume”命令提前创建。 另外,本地存储可作为安装点映射到容器。在这种情况下,“docker run”命令可指定本地目录作为容器内的安装点。第三种选择是使用存储插件直接关联外部存储与容器。 开放访问 在每种方法中,Docker框架都没有提供针对数据的内在安全模型。例如,任何主机目录可安装到容器,包括敏感系统文件夹,例如/etc。这意味着容器可能修改这些文件,因为使用标准简单的Unix权限设置来授予权限。对此,另一种更好的做法是使用非根容器,这涉及在不同的Linux用户ID(UID)下运行容器。这比较容易做,但这意味着构建一种方法来保护每个容器,使用组ID(GID)或者UID作为权限检查。 在这里我们遇到另一个问题:使用非根容器,而本地卷无法正常工作,除非用于运行容器的UID有权限访问/var/lib/docker/volumes 目录。如果不这样做,数据无法访问或创建。打开这个目录会有安全风险;然而,并没有固有方法来按卷设置单独的权限。 如果我们看看外部存储如何安装到容器,很多解决方案只需向运行容器的主机展示块设备(LUN)以及格式化文件系统。这随后展示到容器作为安装点。在这一点上,目录和文件的安全性可在容器内设置,减少我们已经讨论的问题。然而,如果这个LUN/volume在其他地方重复使用,则对其如何安装和使用没有安全控制,因为没有安全模型直接构建到容器/卷映射关系。一切都取决于信任主机上运行的命令。 这里还有一个问题:缺乏多租户性。当我们运行容器时,每个容器实例可能为单独的应用运行。在传统存储部署中,分配到容器的存储应该有一定程度的分离,以确保数据不会被无意或恶意访问。目前没有简单的方法在主机级别做到这一点,只有信任编排工具来运行容器以及映射到数据。 寻找解决方案 这里有些问题是特定于Linux/Unix。例如,安装命名空间的抽象化为我们的数据提供了不同的入口点,然而,并没有权限的抽象化--我无法映射用户1000到用户1001-如果没有物理升级与每个文件及目录相关的ACL(访问控制列表)数据。大规模ACL变更可能会影响性能。对于本地卷来说,Docker可简单地设置主机目录的权限,新卷匹配正在启动容器的UID。 外部卷提供了很好的机会,让我们可以从运行容器主机中的权限结构转移。然而,这意味着我们需要一种机制来映射卷数据到特定容器实例中已知可信应用。请记住,容器并没有固有的“身份”,可根据意愿开始和停止。这使得它很难确定任何单个容器是否是数据卷的所有者。 目前主要解决方案是依靠编排平台来管理容器的运行。我们信任这些系统来映射卷和容器,在很多方面,这并不像传统SAN存储或者虚拟磁盘映射到虚拟机那样。但容器的区别在于其可便携性,以及需要安全机制延伸到公共云。 我们仍然有很多工作要做。对于Docker,对存储初创公司Infinit的收购可能启发他们如何保护持久性数据。这应该可能意味着开发接口让所有供应商可致力于此。 作者:邹铮翻译 来源:51CTO

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册