首页 文章 精选 留言 我的

精选列表

搜索[webpack入门],共10000篇文章
优秀的个人博客,低调大师

ExtJS 2.0入门指南

开始! 我们将讲讲怎么使用ExtJS,来完成一些JavaScript常见的任务。如果你想自己试试,就应该先下IntroToExt2.zip,用来构建已下面的Ext代码。 Zip包里有三个文件:ExtStart.html,ExtStart.js和ExtStart.css。解包这三个文件到Ext的安装目录中(例如,Ext是在“C:\code\Ext\v2.0”中,那应该在"v2.0"里面新建目录“tutorial”。双击ExtStart.htm,接着你的浏览器打开启动页面,应该会有一条消息告诉你配置已完毕。如果出现了Javascript错误,请按照页面上的指引操作。 现在在你常用的IDE中或文本编辑器中,打开ExtStart.js看看。 Ext.onReady(function(){alert("Congratulations! You have Ext configured correctly!");}); Ext.onReady可能是你接触的第一个也可能是在每个页面都要使用的方法。这个方法会在DOM加载全部完毕后,保证页面内的所有元素能被Script引用(reference)之后调用。你可删除alert()那行,加入一些实际用途的代码试试。 Element:Ext的核心 大多数的JavaScript操作都需要先获取页面上的某个元素的引用(reference),好让你来做些实质性的事情。传统的JavaScript做法,是通过ID获取Dom节点的: var myDiv = document.getElementById('myDiv'); 这毫无问题,不过这样单单返回一个对象(DOM节点),用起来并不是太实用和方便。为了要用那节点干点事情,你还将要手工编写不少的代码;另外,对于不同类型浏览器之间的差异,要处理起来可真头大了。 进入Ext.element 对象。元素(element)的的确确是Ext的心脏地带,--无论是访问元素(elements)还是完成一些其他动作,都要涉及它。Element的API是整个Ext库的基础,如果你时间不多,只是想了解Ext中的一两个类的话,Element一定是首选! 由ID获取一个Ext Element如下(首页ExtStart.htm包含一个div,ID名字为“myDiv”,然后,在ExtStart.js中加入下列语句): Ext.onReady(function(){var myDiv = Ext.get('myDiv');}); 再回头看看Element对象,发现什么有趣的东东呢? Element包含了常见的DOM方法和属性,提供一个快捷的、统一的、跨浏览器的接口(若使用Element.dom的话,就可以直接访问底层DOM的节点。); Element.get()方法提供内置缓存(Cache),多次访问同一对象效率上有极大优势; 内置常用的DOM节点的动作,并且是跨浏览器的定位的位置、大小、动画、拖放等等(add/remove CSS classes, add/remove event handlers, positioning, sizing, animation, drag/drop)。 这意味着你可用少量的代码来做各种各样的事情,这里仅仅是一个简单的例子(完整的列表在Element API 文档中)。 继续在ExtStart.js中,在刚才我们获取好myDiv的位置中加入: myDiv.highlight();//黄色高亮显示然后渐退 myDiv.addClass('red');// 添加自定义CSS类 (在ExtStart.css定义) myDiv.center();//在视图中将元素居中 myDiv.setOpacity(.25);// 使元素半透明 获取多个DOM的节点 通常情况下,想获取多个DOM的节点,难以依靠ID的方式来获取。有可能因为没设置ID,或者你不知道ID,又或者直接用ID方式引用有太多元素了。这种情况下,你就会不用ID来作为获取元素的依据,可能会用属性(attribute)或CSS Classname代替。基于以上的原因,Ext引入了一个异常强大的Dom Selector库,叫做DomQuery。 DomQuery可作为单独的库使用,但常用于Ext,你可以在上下文环境中(Context)获取多个元素,然后通过Element接口调用。令人欣喜的是,Element对象本身便有Element.selcect的方法来实现查询,即内部调用DomQuery选取元素。这个简单的例子中,ExtStart.htm包含若干段落(<p>标签),没有一个是有ID的,而你想轻松地通过一次操作马上获取每一段,全体执行它们的动作,可以这样做: // 每段高亮显示 Ext.select('p').highlight(); Element.select在这个例子中的方便性显露无疑。它返回一个复合元素,能通过元素接口(Element interface)访问每个元素。这样做的好处是可不用循环和不分别访问每一个元素。 DomQuery的选取参数可以是一段较长的数组,其中包括W3C CSS3 Dom选取器、基本XPatch、HTML属性和更多,请参阅DomQuery API文档以了解这功能强大的库个中细节。 响应事件 到这范例为止,我们所写的代码都是放在onReady中,即当页面加载后总会立即执行,功能较单一——这样的话,你便知道,如何响应某个动作或事件来执行你希望做的事情,做法是,先分配一个function,再定义一个event handler事件处理器来响应。我们由这个简单的范例开始,打开ExtStart.js,编辑下列的代码: 复制代码 function MyparagraphClick() { alert("dsdf"); } function test(e) { var para = Ext.get(e.target); para.highlight(); Ext.MessageBox.show({title:'para clicked',msg:para.dom.innerHTML,width:400, buttons:Ext.MessageBox.OK,animEl:para}); } Ext.onReady(function() { var myDiv = Ext.get('myDiv'); myDiv.highlight(); myDiv.addClass('red'); myDiv.center(); Ext.select('p').highlight(); Ext.get('myButton').on('click',function() { alert("click me!"); }); var paragraphClick = function(e) { //alert("click wto"); Ext.get(e.target).highlight(); } Ext.select('p').on('click',test); }); 复制代码 现在,为了我们接下来阐述新概念的演示,请观察MessageBox的调用。乍一看,这像一连串的参数传入到方法中,但仔细看,这是一个非常特别的语法。实际上,传入到MessageBox.show的只有一个参数:一个Object literal,包含一组属性和属性值。在Javascript中,Object Literal是动态的,你可在任何时候用{和}创建一个典型的对象(object)。其中的字符由一系列的name/value组成的属性,属性的格式是[property name]:[property value]。在整个Ext中,你将会经常遇到这种语法,因此你应该马上消化并吸收这个知识点! 使用Object Literal的原因是什么呢?主要的原因是“可伸缩性(flexibility)”的考虑",随时可新增、删除属性,亦可不管顺序地插入。而方法不需要改变。这也是多个参数的情况下,为最终开发者带来不少的方便(本例中的MessageBox.show())。例如,我们说这儿的foo.action方法,有四个参数,而只有一个是你必须传入的。本例中,你想像中的代码可能会是这样的foo.action(null, null, null, 'hello').,若果那方法用Object Literal来写,却是这样, foo.action({ param4: 'hello' }),这更易用和易读. Grid Grid是Ext中人们最想先睹为快的和最为流行Widgets之一。好,让我们看看怎么轻松地创建一个Grid并运行。 复制代码 Ext.onReady(function() { var myData =[['Apple',29.89,0.24,0.81,'9/1 12:00am'], ['Ext',83.81,0.28,0.34,'9/12 12:00am'], ['Google',71.72,0.02,0.03,'10/1 12:00am'], ['Microsoft',52.55,0.01,0.02,'7/4 12:00am'], ['Yahoo!',29.01,0.42,1.47,'5/22 12:00am']]; var myReader =new Ext.data.ArrayReader({},[{name:'company'},{name:'price', type:'float'},{name:'change', type:'float'},{name:'pctChange', type:'float'},{name:'lastChange', type:'date', dateFormat:'n/j h:ia'}]); var grid =new Ext.grid.GridPanel({store:new Ext.data.Store({data: myData, reader: myReader}), columns:[{header:"Company", width:120, sortable:true, dataIndex:'company'},{header:"Price", width:90, sortable:true, dataIndex:'price'},{header:"Change", width:90, sortable:true, dataIndex:'change'},{header:"% Change", width:90, sortable:true, dataIndex:'pctChange'},{header:"Last Updated", width:120, sortable:true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex:'lastChange'}], viewConfig:{forceFit:true}, renderTo:'content', title:'My First Grid', width:500, frame:true}); grid.getSelectionModel().selectFirstRow(); }); 复制代码 这看上去很复杂,但实际上加起来,只有四行代码(不包含测试数据的代码)。 第一行创建数组并作为数据源。实际案例中,你很可能从数据库、或者WebService那里得到动态的数据。 接着,我们创建并加载data store, data store将会告诉Ext的底层库接手处理和格式化这些数据。不同的数据类型须在类Reader中指明。 接着,我们创建一个Grid的组件,传入各种的配置值,有: 新的data store, 配置好测试数据和reader 列模型column model定义了列columns的配置 其他的选择指定了Grid所需的功能 最后,通过SelectionModel告诉Grid高亮显示第一行。 不是太困难吧?如果一切顺利,完成之后你会看到像这样的: 使用Ajax 在弄好一些页面后,你已经懂得在页面和脚本之间的交互(interact)原理。接下来,你应该掌握的是,怎样与远程服务器(remote server)交换数据,常见的是从数据库加载数据(load)或是保存数据(save)到数据库中。通过JavaScript异步无刷新交换数据的这种方式,就是所谓的Ajax。Ext内建卓越的Ajax支持,例如,一个普遍的用户操作就是,异步发送一些东西到服务器,然后,UI元素根据回应(Response)作出更新。 客户端: <div id="msg"></div> <div>Name:<input type="text"id="name"/> <input type="button"id="okButton" value="确定"/> </div> 复制代码 Ext.onReady(function() { Ext.get('okButton').on('click',function() { var msg = Ext.get('msg'); msg.load({url:'http://localhost:8080/ajaxDemo/hello', params:'name='+ Ext.get('name').dom.value, text:'Updating'}); msg.show(); }); }); 复制代码 服务器端: 复制代码 import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class hello extends HttpServlet { public hello() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("From Server: hello,ajax!"); out.close(); } public void init() throws ServletException { // Put your code here } } 复制代码 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/14/1242855.html,如需转载请自行联系原作者

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

《javascript入门经典》摘录

JavaScript中可以对内建对象进行扩展。 <html> <head><title>Test of heading method</title> </head> <body> <script LANGUAGE="JavaScript" type="text/javascript"> function addhead (level) { html = "H" + level; text = this.toString(); start = "<" + html + ">"; stop = "</" + html + ">"; return start + text + stop; } String.prototype.heading = addhead; document.write ("This is a heading 1".heading(1)); document.write ("This is a heading 2".heading(2)); document.write ("This is a heading 3".heading(3)); </script> </body> </html> 1,Prototype Prototype is free, open-source software. You can download it from its official website at http://prototype.conio.net/. Prototype is also built into the Ruby on Rails framework for the server-side language Rubysee http://www.rubyonrails.com/ for more information. 2,Script.aculo.us Script.aculo.us by Thomas Fuchs is one such library. It includes functions to simplify drag-and-drop tasks, such as rearranging lists of items. It also includes a number of Combination Effects, which enable you to use highlighting and animated transitions within your pages. 3,AJAX Frameworks The Prototype library, described previously, includes AJAX features. There are also many dedicated AJAX libraries. One of the most popular is SAJAX (Simple AJAX), an open-source toolkit that makes it easy to use AJAX to communicate with PHP, Perl, and other languages from JavaScript. Visit the SAJAX website for details at http://www.modernmethod.com/sajax. 4,Dojo (http://www.dojotoolkit.org/) is an open-source toolkit that adds power to JavaScript to simplify building applications and user interfaces. It adds features ranging from extra string and math functions to animation and AJAX. 5, The Yahoo! UI Library (http://developer.yahoo.net/yui/) was developed by Yahoo! and made available to everyone under an open-source license. It includes features for animation, DOM features, event management, and easy-to-use user interface elements such as calendars and sliders. 6, MochiKit (http://mochikit.com/) is a lightweight library that adds features for working with the DOM, CSS colors, string formatting, and AJAX. It also supports a nice logging mechanism for debugging your scripts. 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/05/12/744215.html,如需转载请自行联系原作者

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

Hadoop学习笔记--入门

HaDoop0.23.0学习笔记 0.23介绍 HadoopMapReduceV2(Yarn)框架简介 原HadoopMapReduce框架的问题 对于业界的大数据存储及分布式处理系统来说,Hadoop是耳熟能详的卓越开源分布式文件存储及处理框架,对于Hadoop框架的介绍在此不再累述,读者可参考Hadoop官方简介。使用和学习过老Hadoop框架(0.20.0及之前版本)的同仁应该很熟悉如下的原MapReduce框架图: 图1.Hadoop原MapReduce架构 从上图中可以清楚的看出原MapReduce程序的流程及设计思路: 首先用户程序(JobClient)提交了一个job,job的信息会发送到JobTracker中,JobTracker是Map-reduce框架的中心,他需要与集群中的机器定时通信(heartbeat),需要管理哪些程序应该跑在哪些机器上,需要管理所有job失败、重启等操作。 TaskTracker是Map-reduce集群中每台机器都有的一个部分,他做的事情主要是监视自己所在机器的资源情况。 TaskTracker同时监视当前机器的tasks运行状况。TaskTracker需要把这些信息通过heartbeat发送给JobTracker,JobTracker会搜集这些信息以给新提交的job分配运行在哪些机器上。上图虚线箭头就是表示消息的发送-接收的过程。 可以看得出原来的map-reduce架构是简单明了的,在最初推出的几年,也得到了众多的成功案例,获得业界广泛的支持和肯定,但随着分布式系统集群的规模和其工作负荷的增长,原框架的问题逐渐浮出水面,主要的问题集中如下: JobTracker是Map-reduce的集中处理点,存在单点故障。 JobTracker完成了太多的任务,造成了过多的资源消耗,当map-reducejob非常多的时候,会造成很大的内存开销,潜在来说,也增加了JobTrackerfail的风险,这也是业界普遍总结出老Hadoop的Map-Reduce只能支持4000节点主机的上限。 在TaskTracker端,以map/reducetask的数目作为资源的表示过于简单,没有考虑到cpu/内存的占用情况,如果两个大内存消耗的task被调度到了一块,很容易出现OOM。 在TaskTracker端,把资源强制划分为maptaskslot和reducetaskslot,如果当系统中只有maptask或者只有reducetask的时候,会造成资源的浪费,也就是前面提过的集群资源利用的问题。 源代码层面分析的时候,会发现代码非常的难读,常常因为一个class做了太多的事情,代码量达3000多行,,造成class的任务不清晰,增加bug修复和版本维护的难度。 从操作的角度来看,现在的HadoopMapReduce框架在有任何重要的或者不重要的变化(例如bug修复,性能提升和特性化)时,都会强制进行系统级别的升级更新。更糟的是,它不管用户的喜好,强制让分布式集群系统的每一个用户端同时更新。这些更新会让用户为了验证他们之前的应用程序是不是适用新的Hadoop版本而浪费大量时间。 新HadoopYarn框架原理及运作机制 从业界使用分布式系统的变化趋势和hadoop框架的长远发展来看,MapReduce的JobTracker/TaskTracker机制需要大规模的调整来修复它在可扩展性,内存消耗,线程模型,可靠性和性能上的缺陷。在过去的几年中,hadoop开发团队做了一些bug的修复,但是最近这些修复的成本越来越高,这表明对原框架做出改变的难度越来越大。 为从根本上解决旧MapReduce框架的性能瓶颈,促进Hadoop框架的更长远发展,从0.23.0版本开始,Hadoop的MapReduce框架完全重构,发生了根本的变化。新的HadoopMapReduce框架命名为MapReduceV2或者叫Yarn,其架构图如下图所示: 图2.新的HadoopMapReduce框架(Yarn)架构 重构根本的思想是将JobTracker两个主要的功能分离成单独的组件,这两个功能是资源管理和任务调度/监控。新的资源管理器全局管理所有应用程序计算资源的分配,每一个应用的ApplicationMaster负责相应的调度和协调。一个应用程序无非是一个单独的传统的MapReduce任务或者是一个DAG(有向无环图)任务。ResourceManager和每一台机器的节点管理服务器能够管理用户在那台机器上的进程并能对计算进行组织。 事实上,每一个应用的ApplicationMaster是一个详细的框架库,它结合从ResourceManager获得的资源和NodeManager协同工作来运行和监控任务。 上图中ResourceManager支持分层级的应用队列,这些队列享有集群一定比例的资源。从某种意义上讲它就是一个纯粹的调度器,它在执行过程中不对应用进行监控和状态跟踪。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。 ResourceManager是基于应用程序对资源的需求进行调度的;每一个应用程序需要不同类型的资源因此就需要不同的容器。资源包括:内存,CPU,磁盘,网络等等。可以看出,这同现Mapreduce固定类型的资源使用模型有显著区别,它给集群的使用带来负面的影响。资源管理器提供一个调度策略的插件,它负责将集群资源分配给多个队列和应用程序。调度插件可以基于现有的能力调度和公平调度模型。 上图中NodeManager是每一台机器框架的代理,是执行应用程序的容器,监控应用程序的资源使用情况(CPU,内存,硬盘,网络)并且向调度器汇报。 每一个应用的ApplicationMaster的职责有:向调度器索要适当的资源容器,运行任务,跟踪应用程序的状态和监控它们的进程,处理任务的失败原因。 新旧HadoopMapReduce框架比对 让我们来对新旧MapReduce框架做详细的分析和对比,可以看到有以下几点显著变化: 首先客户端不变,其调用API及接口大部分保持兼容,这也是为了对开发使用者透明化,使其不必对原有代码做大的改变(详见2.3Demo代码开发及详解),但是原框架中核心的JobTracker和TaskTracker不见了,取而代之的是ResourceManager,ApplicationMaster与NodeManager三个部分。 我们来详细解释这三个部分,首先ResourceManager是一个中心的服务,它做的事情是调度、启动每一个Job所属的ApplicationMaster、另外监控ApplicationMaster的存在情况。细心的读者会发现:Job里面所在的task的监控、重启等等内容不见了。这就是AppMst存在的原因。ResourceManager负责作业与资源的调度。接收JobSubmitter提交的作业,按照作业的上下文(Context)信息,以及从NodeManager收集来的状态信息,启动调度过程,分配一个Container作为AppMstr NodeManager功能比较专一,就是负责Container状态的维护,并向RM保持心跳。 ApplicationMaster负责一个Job生命周期内的所有工作,类似老的框架中JobTracker。但注意每一个Job(不是每一种)都有一个ApplicationMaster,它可以运行在ResourceManager以外的机器上。 Yarn框架相对于老的MapReduce框架什么优势呢?我们可以看到: 这个设计大大减小了JobTracker(也就是现在的ResourceManager)的资源消耗,并且让监测每一个Job子任务(tasks)状态的程序分布式化了,更安全、更优美。 在新的Yarn中,ApplicationMaster是一个可变更的部分,用户可以对不同的编程模型写自己的AppMst,让更多类型的编程模型能够跑在Hadoop集群中,可以参考hadoopYarn官方配置模板中的mapred-site.xml配置。 对于资源的表示以内存为单位(在目前版本的Yarn中,没有考虑cpu的占用),比之前以剩余slot数目更合理。 老的框架中,JobTracker一个很大的负担就是监控job下的tasks的运行状况,现在,这个部分就扔给ApplicationMaster做了,而ResourceManager中有一个模块叫做ApplicationsMasters(注意不是ApplicationMaster),它是监测ApplicationMaster的运行状况,如果出问题,会将其在其他机器上重启。 Container是Yarn为了将来作资源隔离而提出的一个框架。这一点应该借鉴了Mesos的工作,目前是一个框架,仅仅提供java虚拟机内存的隔离,hadoop团队的设计思路应该后续能支持更多的资源调度和控制,既然资源表示成内存量,那就没有了之前的mapslot/reduceslot分开造成集群资源闲置的尴尬情况。 表1.新旧Hadoop脚本/变量/位置变化表 改变项 原框架中 新框架中(Yarn) 备注 配置文件位置 ${hadoop_home_dir}/conf ${hadoop_home_dir}/etc/hadoop/ Yarn框架也兼容老的${hadoop_home_dir}/conf位置配置,启动时会检测是否存在老的conf目录,如果存在将加载conf目录下的配置,否则加载etc下配置 启停脚本 ${hadoop_home_dir}/bin/start(stop)-all.sh ${hadoop_home_dir}/sbin/start(stop)-dfs.sh ${hadoop_home_dir}/bin/start(stop)-all.sh 新的Yarn框架中启动分布式文件系统和启动Yarn分离,启动/停止分布式文件系统的命令位于${hadoop_home_dir}/sbin目录下,启动/停止Yarn框架位于${hadoop_home_dir}/bin/目录下 JAVA_HOME全局变量 ${hadoop_home_dir}/bin/start-all.sh中 ${hadoop_home_dir}/etc/hadoop/hadoop-env.sh ${hadoop_home_dir}/etc/hadoop/Yarn-env.sh Yarn框架中由于启动hdfs分布式文件系统和启动MapReduce框架分离,JAVA_HOME需要在hadoop-env.sh和Yarn-env.sh中分别配置 HADOOP_LOG_DIR全局变量 不需要配置 ${hadoop_home_dir}/etc/hadoop/hadoop-env.sh 老框架在LOG,conf,tmp目录等均默认为脚本启动的当前目录下的log,conf,tmp子目录 Yarn新框架中Log默认创建在Hadoop用户的home目录下的log子目录,因此最好在${hadoop_home_dir}/etc/hadoop/hadoop-env.sh配置HADOOP_LOG_DIR,否则有可能会因为你启动hadoop的用户的.bashrc或者.bash_profile中指定了其他的PATH变量而造成日志位置混乱,而该位置没有访问权限的话启动过程中会报错 由于新的Yarn框架与原HadoopMapReduce框架相比变化较大,核心的配置文件中很多项在新框架中已经废弃,而新框架中新增了很多其他配置项,看下表所示会更加清晰: 表2.新旧Hadoop框架配置项变化表 配置文件 配置项 Hadoop0.20.X配置 Hadoop0.23.X配置 说明 core-site.xml 系统默认分布式文件URI fs.default.name fs.defaultFS hdfs-site.xml DFSnamenode存放nametable的目录 dfs.name.dir dfs.namenode.name.dir 新框架中namenode分成dfs.namenode.name.dir(存放nanametable和dfs.namenode.edits.dir(存放edit文件),默认是同一个目录 DFSdatanode存放数据block的目录 dfs.data.dir dfs.datanode.data.dir 新框架中DataNode增加更多细节配置,位于dfs.datanode.配置项下,如dfs.datanode.data.dir.perm(datanodelocal目录默认权限);dfs.datanode.address(datanode节点监听端口);等 分布式文件系统数据块复制数 dfs.replication dfs.replication 新框架与老框架一致,值建议配置为与分布式cluster中实际的DataNode主机数一致 mapred-site.xml Job监控地址及端口 mapred.job.tracker 无 新框架中已改为Yarn-site.xml中的resouceManager及nodeManager具体配置项,新框架中历史job的查询已从Jobtracker剥离,归入单独的mapreduce.jobtracker.jobhistory相关配置, 第三方MapReduce框架 无 mapreduce.framework.name 新框架支持第三方MapReduce开发框架以支持如SmartTalk/DGSG等非Yarn架构,注意通常情况下这个配置的值都设置为Yarn,如果没有配置这项,那么提交的Yarnjob只会运行在locale模式,而不是分布式模式。 Yarn-site.xml TheaddressoftheapplicationsmanagerinterfaceintheRM 无 Yarn.resourcemanager.address 新框架中NodeManager与RM通信的接口地址 Theaddressoftheschedulerinterface 无 Yarn.resourcemanager.scheduler.address 同上,NodeManger需要知道RM主机的scheduler调度服务接口地址 TheaddressoftheRMwebapplication 无 Yarn.resourcemanager.webapp.address 新框架中各个task的资源调度及运行状况通过通过该web界面访问 Theaddressoftheresourcetrackerinterface 无 Yarn.resourcemanager.resource-tracker.address 新框架中NodeManager需要向RM报告任务运行状态供Resouce跟踪,因此NodeManager节点主机需要知道RM主机的tracker接口地址 实验环境: 操作系统:Gentoo-linux-3.8.13i686 主机名IP: Namenode192.168.254.81 Datanode1192.168.254.91 Datanode2192.168.254.92 需要软件: Javajdk-8-linux-i586.tar.gz Hadoophadoop-2.3.0.tar.gz SshOpenSSH_5.9p1-hpn13v11##系统自带emergeopenssh-client–av 结构介绍: Namenode上部署namenode,resourcemanager,secondarynamenode Datanode1/2上部署datanode,nodemanager Java路径/home/hadoop/java Hadoop路径/home/hadoop/hadoop DFS路径/home/hadoop/DFS Hadooptmp路径/temp/hadoor-${user} 实验步骤: 创建用户---在81,91-92下(root): Useraddhadoop–d/home/hadoop Mkdir/home/hadoop Chown–Rhadoop:hadoop/home/hadoop Chmod–R750/home/hadoop Passwdhadoop 做hadoop账号ssh免验证---在81,91-92下(hadoop): Su–hadoop Ssh-keygen##全部默认 在81下(hadoop) Su-hadoop Cd~/.ssh Cpid_rsa.pubauthorized_keys Foriin`echo819192`;doscphadoop@192.168.254.$i:/home/hadoop/.ssh/;done 测试 如图:免验证打开 注意:第一次使用会有安全提示,确认yes Java的安装(hadoop): #Su-hadoop Tarzxvfjdk1.8.0.tar.gz–C/home/hadoop/ Mv/home/hadoop/jdk1.8.0/home/hadoop/java Hadoop的安装(hadoop): #Su–hadoop Tarzxvfhadoop-2.3.0.tar.gz–C/home/hadoop Mv/home/hadoop/hadoop-2.3.0/home/hadoop/hadoop Java和hadoop权限变更(root) #su–root Chown–Rhadoop:hadoop/home/hadoop/ 设置变量---在81,91-92下 Echo“exportJAVA_HOME=/home/hadoop/java”>>/etc/profile Echo“exportPATH=$PATH:$JAVA_HOME/bin”>>/etc/profile Echo“exportCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:./”>>/etc/profile Echo“HADOOP_HOME=/home/hadoop/hadoop”>>/etc/profile Echo“PATH=$PATH:$HADOOP_HOME/bin”>>/etc/profile Echo“JAVA_LIBRARY_PATH=$HADOOP_HOME/lib/native”>>/etc/profile Source/etc/profile Hadoop配置---在81上: Cd$HADOOP_HOME/etc/hadoop/ Vihadoop.env.xml 修改JAVA_HOME路径(考虑全局变量里面我们刚设置了JAVA_HOME,所以这里可以注销) ,如果修改,修改为: ExportJAVA_HOME=/home/hadoop/java Vicore-site.xml <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://192.168.254.81:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/DFS/hadoop-${user.name}</value> <description>Abaseforothertemporarydirectories.</description> </property> </configuration> Vihdfs-site.xml <configuration> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/DFS/hadoop/name1,/home/hadoop/DFS/hadoop/name2</value> <description>Namedir</description> </property> <property> <name>dfs.namenode.edit.dir</name> <value>/home/hadoop/DFS/hadoop/edit1,/home/hadoop/DFS/hadoop/edit2</value> <description>Editdir</description> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/DFS/hadoop/data1,/home/hadoop/DFS/hadoop/data2</value> <description>Datadir</description> </property> <property> <name>dfs.datanode.data.http.address</name> <value>0.0.0.0:50075</value> <description>Thedatanodehttpserveraddressandport</description> </property> <property> <name>dfs.replication</name> <value>2</value> <description>dfsvalues</description> </property> </configuration> Vimapred-site.xml <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> Viyarn-site.xml <?xmlversion="1.0"?> <configuration> <!--sitespecificYARNconfigurationproterties--> <property> <name>yarn.nodemanager.aux-serivice</name> <value>mapreduce.shuffle</value> </property> <property> <description>TheaddressoftheapplicationsmanagerinterfaceintheRM.</description> <name>yarn.resourcemanager.address</name> <value>192.168.254.81:18040</value> </property> <property> <description>Theaddressoftheschedulerinterface.</description> <name>yarn.resourcemanager.scheduler.address</name> <value>192.168.254.81:18030</value> </property> <property> <description>TheaddressoftheRMwebapplication.</description> <name>yarn.resourcemanager.webapp.address</name> <value>192.168.254.81:18088</value> </property> <property> <description>Theaddressoftheresourcetrackerinterfacce.</description> <name>yarn.resourcemanager.resource-tracker.address</name> <value>192.168.254.81:8025</value> </property> </configuration> Vislaves 192.168.254.91 192.168.254.92 Vimasters 192.168.254.81 将81上面的/home/hadoop/java&hadoop同步到91-92下(hadoop) #su–hadoop Cd Foriin`seq9192`;doscp–r/home/hadoop/*hadoop@192.168.254.$i:/home/hadoop/;done 添加hosts解析---81,91-92(root) echo“192.168.254.81namenode”>>/etc/hosts echo“192.168.254.91datanode1”>>/etc/hosts echo“192.168.254.92datanode2”>>/etc/hosts 本文转自 chengchow 51CTO博客,原文链接:http://blog.51cto.com/chengchow/1397147,如需转载请自行联系原作者

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

elk入门概念详解

开始第一步 我们现在开始进行一个简单教程,它涵盖了一些基本的概念介绍,比如索引(indexing)、搜索(search)以及聚合(aggregations)。通过这个教程,我们可以让你对Elasticsearch能做的事以及其易用程度有一个大致的感觉。 我们接下来将陆续介绍一些术语和基本的概念,但就算你没有马上完全理解也没有关系。我们将在本书的各个章节中更加深入的探讨这些内容。 所以,坐下来,开始以旋风般的速度来感受Elasticsearch的能力吧! 让我们建立一个员工目录 假设我们刚好在Megacorp工作,这时人力资源部门出于某种目的需要让我们创建一个员工目录,这个目录用于促进人文关怀和用于实时协同工作,所以它有以下不同的需求: 数据能够包含多个值的标签、数字和纯文本。 检索任何员工的所有信息。 支持结构化搜索,例如查找30岁以上的员工。 支持简单的全文搜索和更复杂的短语(phrase)搜索 高亮搜索结果中的关键字 能够利用图表管理分析这些数据 索引员工文档 我们首先要做的是存储员工数据,每个文档代表一个员工。在Elasticsearch中存储数据的行为就叫做索引(indexing),不过在索引之前,我们需要明确数据应该存储在哪里。 在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库: Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。 「索引」含义的区分 你可能已经注意到索引(index)这个词在Elasticsearch中有着不同的含义,所以有必要在此做一下区分: 索引(名词)如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是indices 或indexes。 索引(动词)「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。 倒排索引传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。 默认情况下,文档中的所有字段都会被索引(拥有一个倒排索引),只有这样他们才是可被搜索的。 我们将会在倒排索引章节中更详细的讨论。 所以为了创建员工目录,我们将进行如下操作: 为每个员工的文档(document)建立索引,每个文档包含了相应员工的所有信息。 每个文档的类型为employee。 employee类型归属于索引megacorp。 megacorp索引存储在Elasticsearch集群中。 实际上这些都是很容易的(尽管看起来有许多步骤)。我们能通过一个命令执行完成的操作: PUT /megacorp/employee/1 { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] } 我们看到path:/megacorp/employee/1包含三部分信息: 名字 说明 megacorp 索引名 employee 类型名 1 这个员工的ID 请求实体(JSON文档),包含了这个员工的所有信息。他的名字叫“John Smith”,25岁,喜欢攀岩。 很简单吧!它不需要你做额外的管理操作,比如创建索引或者定义每个字段的数据类型。我们能够直接索引文档,Elasticsearch已经内置所有的缺省设置,所有管理操作都是透明的。 接下来,让我们在目录中加入更多员工信息: PUT /megacorp/employee/2 { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests": [ "music" ] } PUT /megacorp/employee/3 { "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about": "I like to build cabinets", "interests": [ "forestry" ] } 结果: [root@master elasticsearch]# 1 2 3 4 5 6 7 8 9 curl-i-XPUT127.0.0.1:9200 /megacorp/employee/1 -d' { "first_name" : "John" , "last_name" : "Smith" , "age" :25, "about" : "Ilovetogorockclimbing" , "interests" :[ "sports" , "music" ] } ' 结果: 集群数据目录多一个了index megacorp名名称的(indices目录是 index名称的复数) [root@master elasticsearch]# 1 ls -l /tmp/elasticsearch/data/elasticsearch-cluster/nodes/0/indices/megacorp/ 1 2 3 4 5 6 7 total24 drwxr-xr-x5elasticsearchelasticsearch4096May1519:320 drwxr-xr-x5elasticsearchelasticsearch4096May1519:311 drwxr-xr-x5elasticsearchelasticsearch4096May1519:322 drwxr-xr-x5elasticsearchelasticsearch4096May1519:313 drwxr-xr-x5elasticsearchelasticsearch4096May1519:334 drwxr-xr-x2elasticsearchelasticsearch4096May1519:33_state 本文转自残剑博客51CTO博客,原文链接http://blog.51cto.com/cuidehua/1773685如需转载请自行联系原作者 cuizhiliang

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

[Phoenix] 一、快速入门

Phoenix作为应用层和HBASE之间的中间件,以下特性使它在大数据量的简单查询场景有着独有的优势 二级索引支持(global index + local index) 编译SQL成为原生HBASE的可并行执行的scan 在数据层完成计算,server端的coprocessor执行聚合 下推where过滤条件到server端的scan filter上 利用统计信息优化、选择查询计划(5.x版本将支持CBO) skip scan功能提高扫描速度 一般可以使用以下三种方式访问Phoenix JDBC API 使用Python编写的命令行工具(sqlline, sqlline-thin和psql等) SQuirrel 一、命令行工具psql使用示例 1.创建一个建表的sql脚本文件us_population.sql: CREATE TABLE IF NOT E

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

docker入门篇

基础知识不回顾了,直接上。 docker的安装与启动 yum remove docker -y yum install docker-io -y #需要先配置好epel源 /etc/init.d/docker start chkconfig docker on 获取镜像 docker pull centos #从docker仓库下载一个镜像例如:docker pull centos:6.7 docker images #列出本地已存在的镜像 docker images centos #查看指定的镜像 运行 # docker run centos /bin/echo'Hello world' # docker run -i -t centos:6.7/bin/bash -i表示输入终端保持打开状态 -t表示开一个伪终端,并绑定到标准输入上 -c限制运行的某个容器的CPU配额【最大默认是1024】 --cpuset-cpus=设置可以绑定使用几个CPU,具体可以看help -d表示后台运行容器,只输出容器的ID到屏幕 -P表示--publish-all=false Publish all exposed ports to random ports --hostname=docker1.demo.com表示修改容器的hsotname --name=lnmp1 表示给启动的容器命名,不用随机名称 --dns=xx.xx.xx.xx自定义DNS服务器地址【不指定该参数的话,就是要外部主机的/etc/resolv.conf来配置容器】 --add-host "www.demo.com:192.168.2.2"在容器的/etc/hosts添加一条指定的DNS解析记录 --expose80 --expose 8080 #暴露端口在外部Expose a port or a range of ports --memory1G限制容器最大使用的内存 *centos后面如果不指定版本,则默认选择latest版本 输入exit或者Ctrl+d退出 # docker run -ti --name test3--hostname=docker1.demo.com --dns=192.168.2.2 --dns=8.8.8.8 lanmp:v1 /bin/bash #复杂的写法 # docker run -d ubuntu:14.04/bin/sh -c "while true; do echo hello world; sleep 1; done"以后台进程模式运行 # docker logs后面跟容器的NAMES 当利用docker run来创建容器时,Docker在后台运行的标准操作包括: 检查本地是否存在指定的镜像,不存在就从公有仓库下载 利用镜像创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 从地址池配置一个ip地址给容器 执行用户指定的应用程序 执行完毕后容器被终止 # docker ps查看在运行中的docker实例进程 # docker logs insane_babbage 查看容器中的标准输出 # docker stop insane_babbage停止某个容器 # docker ps可以看到刚才启动的那个centos容器没有了 # docker ps -a可以看到所有的容器(包括已停止的) # docker start insane_babbage #如果加-i参数可以进入交互式的容器 # docker version查看docker客户端版本和进程的版本信息 ubuntu容器安装软件: 默认安装好的ubuntu docker是没有vim和ping这些命令的。 进入容器后,执行 # apt-get update # apt-get install vim -y 然后vi /etc/apt/sources.list添加阿里云的源地址。 # apt-get install inetutils-ping-y # ping www.qq.com即可 查看帮助信息 # docker只输入docker指令,系统会自动列出全部可用的命令列表 # docker images --help 创建镜像方法1:修改镜像 # docker run -i -t centos:6.7/bin/bash记下容器的ID,例如:e2d6c890682f 在容器中添加LAMP环境 # yum install httpd mysql mysql-server php php-mysql -y # exit退出容器 # docker commit -m "Add LAMPenv" -a "CentOS_LAMP" e2d6c890682f 6.7lamp 提交更新后的副本 -m message -a author # docker images可以看到已经生成了一个镜像 # docker run -i -t 6.7lamp/bin/bash用刚才创建的镜像启动容器 另外,可以使用docker commit -m 'my nignx' e2d6c890682fdemo/my_nginx:v1这种创建带明显标志的镜像。 启动的话使用docker run -d -p 88:80 --name "ningx_1" demo/my_nginx:v1即可。 方法2、dockerfile创建基于centos6.7的nginx的容器 mkdir /opt/docker-file cd /opt/docker-file mkdir nginx && cd nginx vi Dockerfile内容如下: # This is My First Dockerfile # Verson 1.0 # Author: Lee FROM centos:6.7 MAINTAINER Lee ADD pcre-8.36.tar.gz/usr/local/src<--- 1、需要事先把这个tar.gz包拷贝到当前目录下,即和Dockerfile在同一个目录下 ADD nginx-1.11.5.tar.gz/usr/local/src<---2、如果是个压缩包,拷到容器后会自动解压的,无需我们解压操作 RUN rm -fr /etc/yum.repos.d/* RUN wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo RUN wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo RUN yum clean all RUN yum install -y wget gcc gcc-c++ make openssl-devel RUN useradd -s /sbin/nologin -Mwww WORKDIR/usr/local/src/nginx-1.11.5 RUN ./configure--prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status--with-pcre=/usr/local/src/pcre-8.36 && make && make install RUN echo 'daemon off;' >>/usr/local/nginx/conf/nginx.conf RUN sed 's@#user nobody;@user www;@g' nginx.conf ENV PATH/usr/local/nginx/sbin:$PATH EXPOSE 80 CMD ["nginx"] docker build -t dockfile:v2 .这样就可以创建镜像了 启动刚才创建的nginx docker容器的话,使用docker run -d -p 8888:80 dockfile:v2即可。 参数说明: 指令: FROM<image>[:tag>]或者FROM <image>@<digest> #必须是第一个非注释的行,用于指定所用到的基础镜像 MAINTAINER<author's detail> COPY["<src>", ..."<dest>"]复制本地主机的目录到容器里的指定目录 <src>是要复制的源文件或目录,支持通配符 <dest>目标路径,正在创建的镜像文件的文件系统路径(建议使用绝对路径) 说明:所有新复制生成的目录文件的UID和GID都是0 例如:COPY /home/template/server.xml/etc/tomcat/server.xml COPY *.conf /etc/httpd/conf.d/ 注意:src必须是build上下文的路径,即不能使用类似../../conf/*.conf,但是还是可以使用绝对路径例如/home/conf.d/*.conf;src如果是目录的话,递归复制会自动进行;如果有多个src,包括在src上使用了通配符,此时dest必须是目录,而且必须得以/结尾。 dest如果事先不存在,它会被自动创建,包括其父目录。 ADD类似COPY指令,额外还支持复制tar格式的文件及URL路径。【ADD比COPY用得更常见些】 例如:ADD haproxy.cfg /etc/haproxy/haproxy.cfg ADDlogstash_*.cnf /etc/logstash/ ADD http://www.demo.com/download/nginx.conf/etc/nginx/【URL格式指定的源文件,下载完成后其目标文件权限为600】 如果src是一个宿主机上的tar文件,则它将被解压展开成要给目录(类似tar xf命令,如果通过URL下载的是个tar文件,则不会被自动展开) ENV定义环境变量,此些变量可以被当前dockerfile文件中的其它指令所调用,调用格式为$variable_name或${variable_name} 语法: ENV<key> <value> 一次定义一个变量 或者ENV <key>=<value>...一次可以定义多个变量,如果value中有空白字符,要是\进行转义 如:ENV myName="Tom Lee" myDog='wang cai' 说明:ENV定义的环境变量在镜像运行的整个过程中一直存在,因此可以使用docker inspect查看,甚至可以用docker run --env=xxx来修改其值 USER指定运行容器时,或者运行RUN CMD ENTRYPOINT指令指定的程序时使用的用户名或者UID 格式:USER <UID>|<Username> WORKDIR为后续的RUN、CMD、ENTRYPOINT、COPY、ADD指令配置工作目录 如: WORKDIR/a WORKDIRb WORKDIRc RUNpwd 则最终路径为/a/b/c 另外, WORKDIR还可以调用由ENV定义的环境变量的值,如:WORKDIR $STATEPATH ENTRYPOINT VOLUME在目标镜像文件中创建一个挂载点,用来挂载主机上的卷或其他容器的卷。一般用来存放数据库和需要保持的数据等。 VOLUME<mountpoint> 例如:VOLUME ["/data/mysql","/data/Images"] 注意:如果mountpoint路径下事先有文件存在,则在挂载完成后,会同时显示当前的文件和挂载前的文件(AUFS的叠加原理)。 RUN 每个RUN都会另起一层,所以建议将多个命令放到一行,减少AUFS的层数。 格式: RUN <command> #会启动一个shell解释器 或RUN ["<executeable>","<param1>","<parma2>",...] #不会启动shell解释器 例如: RUNyum install iproute nginx && yum clean all RUN['/bin/bash','-c','yum','install','httpd'] CMD设定在docker run时默认执行的命令 格式:CMD <command>或CMD ["<executeable>","<param1>","<parma2>"] 或CMD["<param1>","<param2>",...]为ENTRYPOINT指令指定的程序提供默认参数。 如果dockerfile中存在多个CMD指令,则只有最后一个生效。 例如: CMD["/usr/sbin/httpd","-c","/etc/httpd/conf/httpd.conf"] ENTRYPOINT类似CMD指令,但其不会被docker run的命令行参数指定的指令所覆盖。且这些命令行参数会被当中参数送给ENTRYPOINT指令指定的程序 如果运行docker run时使用了--entrypoint选项,则此选项的参数可以覆盖掉dockerfile默认的entrypoint参数。 格式: ENTRYPOUNT<command> ENTRYPOUNT["executeable","<param1>","<param2>",...] 例如: 注意: 如果CMD和ENTRYPOINT都存在的话,则CMD的指令会被附加到ENTRYPOINT后,变成ENTRYPOINT的参数。 EXPOSE用于为容器指定要暴露的端口 格式:EXPOSE<port>[/protocol>][<port>[/<protocol>]]... 如: EXPOSE11211/tcp 11211/udp ONBUILD配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令 例如:ONBUILD ADD my.cnf /etc/mysql/my.cnf 注意:ONBUILD不能自我嵌套,且不会触发。 导出镜像 # docker save -o/root/centos_lamp_v3.tar centos/lamp:v3 导入镜像 # docker load--input /root/centos_lamp_v3.tar 或者docker load </root/centos_lamp_v3.tar #这将导入镜像以及其相关的元数据信息(包括标签等) 移除镜像 # docker rmicentos/lamp:v3 注意:在删除镜像之前要先用dockerrm删掉依赖于这个镜像的所有容器。 想要删除untagged images,也就是那些id为<None>的image的话可以用 # docker rmi$(docker images | grep "^<none>" | awk "{print $2}") 要删除全部image的话 # docker rmi$(docker images -q) 删除已停止的容器 # docker rm -f$(docker ps -a -q) 移除容器 # docker rm5d6da6754d01 停止所有的container,这样才能够删除其中的images: # docker stop$(docker ps -a -q) 如果想要删除所有container的话再加一个指令: # docker rm$(docker ps -a -q) 从本地文件系统导入一个镜像 要从本地文件系统导入一个镜像,可以使用openvz(容器虚拟化的先锋技术)的模板来创建:openvz的 模板下载地址为templates。 比如,先下载了一个ubuntu-14.04的镜像,之后使用以下命令导入: catubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04 上传镜像 docker pushouruser/sinatra 进入容器 在使用-d参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,有很多种方法,包括使用docker attach命令或nsenter工具等 # docker attach容器NAME 或者docker exec-ti容器ID /bin/bash 但是使用attach命令有时候并不方便。当多个窗口同时attach到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。使用attach进到容器后要退出的话,只能关闭xshell了,使用exit会导致整个容器的退出。 nsenter这个进入容器的命令也很好用(如果没有的话需要安装util-linux-ng)。 方法: dockerinspect --format"``.`State`.`Pid`"容器NAME或者容器ID号 #结果会输出一个容器的pid号 nsenter --target容器的pid号--mount --uts --ipc --net--pid 上面2条命令可以做成脚本,in.sh内容如下: #!/bin/bash CNAME=$1 CPID=$(dockerinspect --format"``.`State`.`Pid`" $CNAME) nsenter--target $CPID --mount --uts --ipc --net --pid sh in.sh容器的NAME或者ID号,即可进入容器。 导出容器快照到本地文件 # docker ps -a # dockerexport 容器名称> ubuntu.tar 导入容器快照为镜像 # cat ubuntu2.tar |dockerimport- test/ubuntu:v1 # docker images 自己基于centos构建nginx容器: 首先启动一个centos容器,然后在里面安装nginx(我这里是yum安装的nginx)。 修改nginx的配置文件,加上daemon off;参数。 然后继续。下面有2种方法启动容器时候让它自动启动nginx 方法1: dockercommit -m 'nginx_v1' eb919426f773 6.7_nginx_v1 dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /usr/sbin/nginx 这样就可以了。 方法2: 修改容器的/etc/bashrc加上/usr/sbin/nginx -c/etc/nginx/nginx.conf dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /bin/bash docker私有仓库的搭建 【作为仓库的虚拟机IP为:192.168.2.11】: #必须先启动docker registry【centos6上是这样的。在centos7上则变成了一个守护进程,需要用systemctl来启动】 # docker pullregistry # docker run -d-p 5000:5000 -v /opt/data/registry:/tmp/registry registry # docker ps记下容器NAME为kickass_wright #默认情况下,仓库会被创建在容器的/tmp/registry下。可以通过-v参数来将镜像文件存放在本地的指定路径。 # docker images列出当前的镜像 # docker tag88e44a5cbd17 192.168.2.11:5000/centos/lamp 格式:dockertag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] # docker images Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。 修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。 # docker stopkickass_wright停掉registry容器 #/etc/init.d/docker restart 重启docker # docker startkickass_wright启动registry容器 # docker push192.168.2.11:5000/centos/lamp 将本地镜像推送到本机上的私有服务器上 这样本地镜像就是上次到私有docker仓库了。 我们可以在其他节点测试能否下载这个镜像。如果没问题的话,就可以在本机上删除原有的docker镜像,如下: # docker rmi 192.168.2.11:5000/centos/lamp 在Node2节点(192.168.2.12)测试: # yum installdocker-io -y 修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。 #/etc/init.d/docker restart 重启docker # docker pull192.168.2.11:5000/centos/lamp从192.168.2.11的私有仓库下载镜像 # docker images可以看到已经下载好了相关的镜像 docker的监控命令: docker ps [-a] docker images docker statsContainer_name #实时查看某个容器的负载情况 docker topContainer_name #实时查看某个容器的状态统计(类似top命令) dockerinspect #查看容器或镜像的底层信息 例如:docker inspect-f'``.`Config`.`Hostname`'d413082da04e类似ansible的ansible -m setup的输出格式 此外,还有谷歌提供的CAdvisor web界面的监控工具;Scout工具,Data Dog工具,等。具体可参考: http://dockone.io/article/397 数据卷: 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性: 数据卷可以在容器之间共享和重用 对数据卷的修改会立马生效 对数据卷的更新,不会影响镜像 卷会一直存在,直到没有容器使用 *数据卷的使用,类似于Linux下对目录或文件进行mount 下面创建一个web容器,并加载一个数据卷到容器的/webapp目录: # docker run -d-P --name web -v /webapp training/webapp python app.py #这样只写名容器中的目录不写宿主机的目录的话,实际上是在宿主机的/var/lib/docker/volumes/xxxx/目录下的。不常用这种写法。 -v标记来创建一个数据卷并挂载到容器里。在一次run中多次使用可以挂载多个数据卷 *注意:也可以在Dockerfile中使用VOLUME来添加一个或者多个新的卷到由该镜像创建的任意容器。 挂载一个主机目录src/webapp作为容器的数据卷: # docker run -d-P --name web2 -v /src/webapp:/opt/webapp training/webapp python app.py #格式:-v本地路径:容器路径 *上面的命令加载主机的/src/webapp目录到容器的/opt/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。 *本地目录的路径必须是绝对路径,如果目录不存在Docker会自动为你创建它。 *注意:Dockerfile中不支持这种用法,这是因为Dockerfile是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。 Docker挂载数据卷的默认权限是读写,用户也可以通过:ro指定为只读。 # sudo docker run-d -P --name web -v/src/webapp:/opt/webapp:rotraining/webapppython app.py -v标记也可以从主机挂载单个文件到容器中 # docker run --rm-it -v ~/.bash_history:/.bash_history ubuntu /bin/bash【不同shell版本有所不同】 *注意:如果直接挂载一个文件,很多文件编辑工具,包括vi或者sed --in-place,可能会造成文件inode的改变,从Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。 数据卷容器: 如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。 数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。 首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata: # docker run -i-t-v /dbdata--name dbdataubuntu:12.04/bin/bash 再启动2个容器测试 # docker run -i-t--volumes-from dbdata--name db1 ubuntu:12.04/bin/bash # docker run -i-t--volumes-from dbdata--name db2 ubuntu:12.04/bin/bash #注意:--volumes-from后面跟的是具备容器卷的那个容器名 此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。[即便原来的那个数据卷容器已经停止了] 查看数据卷实际的存放路径: docker inspect -f``.`Volumes`数据卷容器的NAME或ID map[/dbdata:/var/lib/docker/volumes/7c12ca73fe29f884ea5bee12c54da521c7450705264f76fe8629877302cd48aa/_data] 可以看到这个容器卷是把文件写入到/var/lib/docker/volumes下面的某个很长的字符串的目录下的_data/里面 容器和宿主机间文件拷贝的解决方法: docker ps获取目标容器的ID或者容器的名称 #我这里的是容器ID为52261df2fab6 docker inspect-f'``.`Id`'容器的ID #获取容器的ID全名称 得到一串类似52261df2fab612b24b3502c4ad98c22aff70ce9fa641c5c9f735ac2415e92da3 cp /root/test.log/var/lib/docker/devicemapper/mnt/52261d...xxx/rootfs/root/ #这样就把宿主机的test.log拷贝到容器的/root/目录下了。 #说明:上面的这个方法在CentOS6.7通过yum安装的docker-io测试通过。我另一台测试机安装的是docker-engine,则根本没有/rootfs/这个目录。 还可以使用多个--volumes-from参数来从多个容器挂载多个数据卷。 # docker run -i-t-v /dbdata--name dbdata ubuntu:12.04/bin/bash # docker run -i-t-v /webdata--name webdata ubuntu:12.04/bin/bash # docker run -i-t--volumes-from dbdata --name db1 --volumes-fromwebdata --name web1ubuntu:12.04 /bin/bash 此外,也可以从其他已经挂载了数据卷的容器来挂载数据卷。 *注意: 使用--volumes-from参数所挂载数据卷的容器自己并不需要保持在运行状态。 如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会被自动删除。 如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用"docker rm -v容器名"命令来指定同时删除关联的容器。这可以让用户在容器之间升级和移动数据卷。另外,如果启动时候加了--rm参数,则容器关闭时自动删除容器并删除卷。 利用数据卷容器来备份数据 # docker run -i-t-v /dbdata--namedbdataubuntu:12.04 /bin/bash # cp /etc/issue/etc/group /dbdata 另外启动一个容器,对刚才的容器数据进行备份操作 # docker run--volumes-fromdbdata-v $(pwd):/backup --name bk1 ubuntu:12.04 tar czf/backup/backup.tar.gz /dbdata #格式:dockerrun--volumes-from要备份的容器名-v宿主机目录:/backup ubuntu:12.04 tar czf /backup/xx.tar.gz需要备份的容器的卷名称 *容器启动后,使用了tar命令来将dbdata卷备份为容器下的/backup/backup.tar.gz,这个容器执行完就自动退出了(因为没有-ti或-d参数), *同时在宿主机下当前目录下生成backup.tar.gz压缩文件(参数-v $(pwd):/backup就是这个作用). 利用数据卷容器来恢复数据 如果要恢复数据到一个容器,首先创建一个带有数据卷的容器dbdata2。 # docker run -it-v /dbdata --name dbdata2 ubuntu:12.04 /bin/bash 随便在/dbdata里面复制些文件,以便后面恢复数据时用于识别。 然后创建另一个容器,挂载dbdata2的容器,并使用tar解压备份文件到挂载的容器卷中。 #docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu:12.04 tar xf/backup/backup.tar.gz 本文转自 lirulei90 51CTO博客,原文链接:http://blog.51cto.com/lee90/1878276,如需转载请自行联系原作者

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

敏捷个人入门指南

为了让加入会员的朋友知道如何循序渐进的学习敏捷个人,我想还是写一点文字出来,这样大家可能知道应该如何去做 快速了解敏捷个人 敏捷个人从2009年至今,经过不断的实践和总结,不断丰富并精炼,形成了一套高效的知行合一的个人体系化成长方法,并已经帮助数千人开启意识层面,并走上实践旅程,去找到真正的自己。 适合人群:如果你希望成为一个有目标、有思想、有结果的人,不管什么职业,敏捷个人都是你最好的伙伴和教练使命宣言:做一个懂生活、爱学习、要行动的幸福影响者理念:简化生活,平衡成长 价值观:快乐、高效、平衡网站:www.zhoujingen.cn徽标: 敏捷个人logo是由一个三色组成的一个人,原型来源于《维特鲁威人》,达芬奇努力绘出了完美比例的人体。这幅画体现了一种均衡,而均衡由来自于比例。 人的外形,表示敏捷个人是关注的是人,帮助愿意成长的人提升生命质量,享受幸福生活。这里指的人是只从自身开始,然后关联更多的人 红、绿、蓝是三种基本色光,简单但又多彩的可以组合成各种丰富的颜色,意蕴着简化生活的理念 人体中自然的中心点是肚脐,而我们也在寻找着属于自己的定位,并在生活方向盘各维度划分不同的精力,意蕴着平衡成长的理念 不同颜色代表着头手心,蓝色的头脑代表着理性的思维,绿色的身体代表着行动的执行,红色的心代表着对生活的热情和追求,三者一致方能达到知行合一 敏捷个人体系 敏捷个人是一个经过多年研习和实践的一套自我成长定位体系,目前包含自我导向型学习、时中法目标管理和敏捷生活三大系统,分别有快乐个人练习、高效个人练习和平衡个人练习来帮助大家去循序渐进的了解。 快乐个人练习:快乐源自从痛苦中走出,每天三个话题的思考,让你对原以为知道的事物进行直觉的感知,享受孤独的时刻,不带目的性及评价性的觉察,从发现事物中找回自己,给自己带来真正的快乐。 高效个人练习:让你拥有一套自己的简单高效系统,学习去思考抓住重点,一步一步落实到每一天,做正确的事并且正确的做事。 平衡个人练习:健康、精神、家庭、工作、财富、休闲、人际、贡献,如小丑手中的戏球,你每天忙碌的正是要努力转动这些球,不但要稳,还希望转出色彩,而这关键在于掌握平衡,这不仅需要技巧,还需要勇气,你来吗? 如何开始学习敏捷个人 敏捷个人每个练习都有不同适应阶段和人群,可以查看练习说明。不过经常有人问我先开始哪个练习,我才意识到选择多了未必是好事,所以索性我指定一个顺序。 阅读本篇以上文字,了解敏捷个人 注册会员,点击下载手机应用,安装我们的Android应用。非Android手机请直接点击访问网址 先做高效个人练习,开始你的第一个练习。如何进行练习,请参考如何进行敏捷个人练习 按照练习要求进行思考,最好使用手机应用实践,更多手机应用功能,请参考敏捷个人手机应用说明 练习期间在QQ群中进行提问交流,与大家一起成长 关注QQ群中组织的线上线下活动通知,积极参加 如果你时间充裕,那么可以同时进行快乐个人练习 完成高效个人练习后,进行平衡个人练习 -------------------------------------- 本文将根据反馈不断更新完善 本文转自 jingen_zhou 51CTO博客,原文链接:http://blog.51cto.com/zhoujg/1562432,如需转载请自行联系原作者

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

ElasticSearch入门 —— 集群搭建

一、环境介绍与安装准备 1、环境说明 2台虚拟机,OS为ubuntu13.04,ip分别为xxx.xxx.xxx.140和xxx.xxx.xxx.145。 2、安装准备 ElasticSearch(简称ES)由java语言实现,运行环境依赖java。ES 1.x版本,官方推荐至少使用jdk1.6的环境,建议使用oracle java,可以去官网下载,本文使用jdk-7u51-linux-i586.gz。ES可以去官网下载,也可以在这里下载,本文使用elasticsearch-1.0.1.tar.gz。 二、安装 1、安装JAVA 关于java的安装,请参照这里。 2、ES安装 (1)解压elasticsearch-1.0.1.tar.gz,sudo tar -zvxf elasticsearch-1.0.1.tar.gz,在当前路径生成目录:elasticsearch-1.0.1;为该目录做一个软连接ln -selasticsearch-1.0.1 elasticsearch。完成之后,目录结构如下图: (2)配置es。这里只做最简单的配置,修改ES_HOME/config/elasticsearch.yml文件,将node.name的值设置为“test-node1”,表示当前这个es服务节点名字为test-node1。 (3)启动ES。进入ES安装目录,执行命令:bin/elasticsearch -d -Xms512m -Xmx512m,然后在浏览器输入http://ip:9200/,查看页面信息,是否正常启动。status=200表示正常启动了,还有一些es的版本信息,name为配置文件中node.name的值。 (4)在另外一台机器上,安装同样的步骤安装ES,因为至少2台服务才算集群嘛!注意,在配置时,将node.name的值设置为test-node2,总之必须和之前配置值不同。 两台es服务同时起来,因为配置文件中均默认cluster.name=elasticsearch,所以这两台机器自动构建成一个集群,集群名字为elasticsearch。 3、elasticsearchservicewrapper安装 这个是对elasticsearch执行命令的包装服务,安装之后,方便elasticsearch的启动,停止等等操作。 (1)下载elasticsearchservicewrapper git clonehttps://github.com/elasticsearch/elasticsearch-servicewrapper,然后将目录下的service目录拷贝至ES_HOME/bin目录下。 (2)简单配置jvm的内存 修改ES_HOME/bin/service/elasticsearch.conf,set.default.ES_HEAP_SIZE=1024,该值根据机器的配置可自定义。 (3)安装启动服务 执行命令:ES_HOME/bin/service/elasticsearch install (4)启动/停止/重启服务 执行命令:ES_HOME/bin/service/elasticsearch start/stop/restart 4、插件安装 集群安装成功之后,需要对集群中的索引数据、运行情况等信息进行查看,索引需要安装一些插件,方面后续工作。工欲善其事必先利其器,下面介绍几个实用的插件: (1)head 和插件名字一样,首推这个插件。通过head,可以查看集群几乎所有信息,还能进行简单的搜索查询,观察自动恢复的情况等等。 执行下面的命令开始安装:sudo elasticsearch/bin/plugin -install mobz/elasticsearch-head 记得两台机器都安装一下哦。安装完成之后,在浏览器输入:http://ip:9200/_plugin/head/ ,可以查看显示效果。如下图: cluster health:green (2, 20) : 表示该集群目前处于健康状态,集群包含2台机器,索引总共20个分片。粗线绿框表示主分片,细线绿框为备份分片。 还有很多功能,请读者自己去体验。 (2)bigdesk bigdesk是集群监控插件,通过该插件可以查看整个集群的资源消耗情况,cpu、内存、http链接等等。 执行命令安装:sudo elasticsearch/bin/plugin -install lukas-vlcek/bigdesk 安装完成之后,在浏览器输入:http://ip:9200/_plugin/bigdesk/#nodes ,显示界面如下: 点击test-node1节点,可以查看单个节点的资源使用情况,包括JVM、Thread Pools、OS、Process、HTTP&Transport、Indice、File system。 ES的插件非常之多,请参考ES插件大全。 本文转自gaofeng36599 51CTO博客,原文链接:http://blog.51cto.com/786678398/1627402

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

深度学习入门指南

更多深度文章,请关注:https://yq.aliyun.com/cloud 简介 机器学习技术为现代社会的许多领域提供了强大的技术支持:从网络搜索到社交网络的内容过滤,再到电子商务网站的产品推荐。机器学习技术正越来越多的出现在消费级产品上,比如照相机和智能手机。 机器学习系统可用于识别图像中的对象,将语音转换成文本,选择搜索结果的相关项,以及匹配新闻、帖子或用户感兴趣的其他东西。 类似的应用越来越多,它们都使用了一种叫做深度学习的技术。 深度学习(也称为深层结构学习、层次学习或深度机器学习)是基于对数据中的高级抽象进行建模的算法,它属于机器学习的分支。最简单的例子,你可以有两组神经元:接收输入信号的神经元和发送输出信号的神经元。当输入层接收到输入时,它将输入的修改版本传递给下一层。在深层网络中,输入和输出层之间有很多层(层并不是由神经元构成,这里只是为了帮助你思考),这些层允许算法使用多个处理层,这些层包含了多个线性和非线性变换。 近来,深度学习技术使得机器学习发生了革命性的变化,并出现了很多伟大的成果。 它们大大改进了语音识别、视觉对象识别、对象检测以及许多其他领域(如药物发现和基因组学)的技术。 “深度学习”这个术语最早由Dechter(1986)引入机器学习,由Aizenberg等人(2000)引入人工神经网络(NN)。 深度学习的进一步普及得益于由Alex Krizhevsky发明的被称为“AlexNet”的卷积网络架构的出现。“AlexNet”在2012年的ImageNet比赛中击败了其他所有的图像处理算法,开创了在图像处理中使用深度学习架构的先河。 深度学习架构 生成式深度架构,旨在描述用于模式分析或合成目的的观测数据或可见数据的高阶相关特性,以及描述可见数据及其关联类的联合统计分布的特征。在后一种情况下,使用贝叶斯规则可以将这种类型的架构变成辨别式深度架构。 辨别式深度架构,旨在直接提供模式分类的辨别力,通常通过描述基于可见数据种类的后验分布来描述。 混合式深度架构,其目的是辨别,但通常辅以通过更好的优化或规则化的生成架构的结果,或者是其辨别标准被用来学习类别1中的任何一个深度生成模型的参数 尽管深度学习架构的分类很复杂,但在实践中经常用到的有深度前馈网络、卷积网络和循环网络。 深度前馈网络 前馈网络,通常被称为前馈神经网络或多层感知器(MLP),它是典型的深度学习模式。 前馈网络的目标是逼近某个函数f。例如,对于一个分类器,y=f(x)表示的是将输入x映射到类别y。前馈网络定义了一个映射 y=f(x;θ),并学习能产生最佳逼近函数的参数θ的值。 简单来说,网络可以定义为输入、隐藏和输出节点的组合。数据从输入节点流入,在隐藏节点中进行处理,然后通过输出节点产生输出。信息流经从x评估的函数,通过用于定义f的中间计算,最后到输出y。该网络中没有反馈连接,其中模型的输出反馈到自身,因此模型被称为前馈网络。该模型如图[1]所示。 图[1]:前馈神经网络 卷积神经网络 Source 在机器学习中,卷积神经网络(CNN或ConvNet)是一种前馈人工神经网络,其神经元之间的连接模式是受动物视觉皮层组织的启发而发明出来的。 个别皮质神经元对受限区域的刺激响应称为感受野。不同神经元的感受野部分重叠,这使得这些感受野像瓦片一样平铺。 单个神经元对其感受野内的刺激的反应可以用卷积运算近似地数学化。卷积网络的灵感来自于生物学,是多层感知器的变体。它在图像和视频识别、推荐系统和自然语言处理中具有广泛的应用。 LeNet是第一个卷积神经网络,它推动了深度学习领域的发展。自1988年以来,Yann LeCun的这项开创性工作多次成功迭代后成为了LeNet5。当时的LeNet架构主要用于字符识别,如阅读邮政编码、数字等等。 图[2]:一个简单的卷积神经网络模型 ConvNet有四个主要组件,如图2所示: 卷积层 激活函数 池化层 完全连接层 卷积层 卷积层基于术语“卷积”,它是对两个变量执行数学运算(f*g),以产生第三个变量。 它与互相关类似。 卷积层的输入是一幅 m x m x r 的图像,其中m是图像的高度和宽度,r是通道数,例如,对于RGB图像,r = 3 。 卷积层有大小为n x n x q的k个过滤器(或内核),其中n小于图像的维度,并且q小于等于通道数r,并且每个内核都可以不同。 激活函数 要实现复杂的映射函数,需要有非线性的激活函数,这样引入非常重要的非线性属性,使之能够近似于任何函数。激活函数对于压缩来自神经元的无界线性加权和也是非常重要的。这对于避免在处理层次上积累高值非常重要。有很多经常被用到的激活函数,比如Sigmoid、tanh和ReLU。 池化层 池化是一个基于样本的离散化过程。它的目标是对输入表示(图像、隐藏层输出矩阵等等)进行降采样,减少其维度,并允许对包含在子区域中的特征进行假设。 这样做的部分原因是为了提供一种抽象的表示形式来避免过度拟合。同样,它通过减少要学习的参数个数来降低计算成本,并为内部表示提供基本的转化恒定性。 比较突出的池化技术有:最大池化,最小池化和平均池化。 图[3]:2*2过滤器的最大池化示例 完全连接层 术语“完全连接”意味着上一层中的每个神经元都连接到下一层的每个神经元。完全连接层是传统的多层感知器,它使用softmax激活函数或输出层中的任何其他类似函数。 循环神经网络 在传统的神经网络中,我们假设所有的输入(和输出)是相互独立的。但是对于许多的任务来说,这是一个很糟糕的假设。如果你想预测一个句子中的下一个单词,你最好知道哪些前面的单词是什么。 RNN之所以称为循环,因为它们对序列的每个元素执行相同的任务,而输出依赖于先前的计算。还有一种理解RNN的方法,我们可以认为它有“记忆”的,它会捕获到截至目前计算出来的所有信息。 RNN中有循环,这使得在读入输入时能够跨神经元传递信息。在图[4]中,x_t是某种输入,A是RNN的一部分,h_t是输出。RNN有一些特殊的类型,比如LSTM、双向RNN,GRU等等。 图[4]:RNN模型 RNN可用于NLP、机器翻译、语言建模、计算机视觉、视频分析、图像生成、图像字幕等,这是因为在RNN中可以放置任意数量的输入和输出,并让它们一一对应、多对多对应。它架构存在多种形式,如图[5]所示。 图[5]:RNN描述了对矢量序列的操作 应用 在深度学习领域已经有了很多的研究,并且有很多特别的问题都使用深度学习模型得到了解决。这里有一些深度学习方面的优秀应用: 黑白图像彩色化 深度学习可用于参照照片中的对象及其上下文来对图像进行着色,就像人类进行着色一样。这个应用需使用非常大的卷积神经网络和监督层,通过添加颜色来重现图像。 机器翻译 文本翻译可以在没有对序列进行任何预处理的情况下进行,它允许算法学习单词之间的依赖关系及其与另一种语言之间的映射。大型LSTM循环神经网络的堆叠网络可用于机器翻译。 照片中物体的分类及检测 该任务是将照片中的对象归类到已知的对象组中去。在样例评测中,通过使用非常大的卷积神经网络能够获得非常好的结果。 Alex Krizhevsky等人在ImageNet分类中取得的突破性成果,被称为AlexNet。 自动手写生成 给定一个手写示例语料库,然后为给定的单词或短语生成新的笔迹。在笔迹样本被创建时,笔迹将作为一系列的坐标提供给笔。通过这个语料库,算法会学习笔的运动与字母之间的关系,然后生成新的示例。 自动打游戏 在这个应用中,模型将学习如何仅基于屏幕上的像素点来玩电脑游戏。这在深度增强模型领域中是一个非常难的任务,因为这个,DeepMind(现在是Google的一部分)赢得了很高的声誉。 生成模型聊天机器人 使用基于序列的模型来创建聊天机器人,该机器人在很多真实的对话数据集上进行训练,并学会生成自己的答案。要了解更多的详细信息,请访问这个链接。 总结 从本文可以得到这样的结论:深度学习模型可以用于各种任务,因为它能够模拟人脑。截止目前,专家们已经在这方面做了大量的研究,而且在不久将还有许多研究工作要做。尽管目前还存在信任问题,但在不久的将来,这个问题将会变得更加明朗。 文章原标题《A Beginners Guide to Deep Learning》,作者:Kumar Shridhar,译者:夏天,审校:主题曲。 文章为简译,更为详细的内容,请查看原文 本文由北邮@爱可可-爱生活老师推荐,阿里云云栖社区组织翻译。

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

Appium入门示例(Java)

一、环境准备: 见我另一篇文章:http://www.cnblogs.com/puresoul/p/4696638.html 二、使用Eclipse直接创建案例工程 1、打开Eclipse,【File】-->【New】-->【Project】 2、选择【Java Project】-->【Next】 3、输入工程名称Appium_demo,点击【Finish】 4、右键点击工程 New-Folder,新建两个文件夹:apps和libs,目录结构如下: 三、导入测试的类库 1、导入Selenum类库:http://docs.seleniumhq.org/download/ 1)selenium-server-standalone-2.44.0.jar 2)selenium-java-2.44.0.zip 2、导入Appium类库: 1)java-client-1.2.1.jar 3、右键点击工程空白处,选择【Build Path】-->【Configure Build Path】 四、下载测试APK 1、下载测试的文件ContactManager.apk:https://github.com/appium/sample-code/tree/master/sample-code/apps/ContactManager 2、将下载的apk放到项目的apps目录下 五、建立package包和案例文件 1、在src文件夹上右键单击,【New】-->【package】,输入包名:com.glen.demo,点击【Finish】 2、在package下新建类:ContactsTest.java,如下: 下载地址:https://github.com/appium/sample-code/tree/master/sample-code/examples/java/junit/src/test/java/com/saucelabs/appium 1 package com.glen.demo; 2 3 import io.appium.java_client.AppiumDriver; 4 import org.junit.After; 5 import org.junit.Before; 6 import org.junit.Test; 7 import org.openqa.selenium.By; 8 import org.openqa.selenium.WebElement; 9 import org.openqa.selenium.remote.CapabilityType; 10 import org.openqa.selenium.remote.DesiredCapabilities; 11 12 import java.io.File; 13 import java.net.URL; 14 import java.util.List; 15 16 17 public class ContactsTest { 18 private AppiumDriver driver; 19 @Before 20 public void setUp() throws Exception { 21 //设置apk的路径 22 File classpathRoot = new File(System.getProperty("user.dir")); 23 File appDir = new File(classpathRoot, "apps"); 24 File app = new File(appDir, "ContactManager.apk"); 25 26 //设置自动化相关参数 27 DesiredCapabilities capabilities = new DesiredCapabilities(); 28 capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); 29 capabilities.setCapability("platformName", "Android"); 30 capabilities.setCapability("deviceName", "Android Emulator"); 31 32 //设置安卓系统版本 33 capabilities.setCapability("platformVersion", "4.3"); 34 //设置apk路径 35 capabilities.setCapability("app", app.getAbsolutePath()); 36 37 //设置app的主包名和主类名 38 capabilities.setCapability("appPackage", "com.example.android.contactmanager"); 39 capabilities.setCapability("appActivity", ".ContactManager"); 40 41 //初始化 42 driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 43 } 44 45 @Test 46 public void addContact(){ 47 WebElement el = driver.findElement(By.name("Add Contact")); 48 el.click(); 49 List<WebElement> textFieldsList = driver.findElementsByClassName("android.widget.EditText"); 50 textFieldsList.get(0).sendKeys("Some Name"); 51 textFieldsList.get(2).sendKeys("Some@example.com"); 52 driver.swipe(100, 500, 100, 100, 2); 53 driver.findElementByName("Save").click(); 54 } 55 56 @After 57 public void tearDown() throws Exception { 58 driver.quit(); 59 } 60 } 六、 启动Android模拟器(也可以连接真机) 1、cmd输入:android avd,选择模拟器,点击【Start】即可。具体可参考:http://www.cnblogs.com/puresoul/p/4597211.html 2、启动好后,cmd输入:adb devices,确定设备是否连接上,如下图连接成功: 七、 启动Appium 方法一:cmd输入:appium 方法二: 1、直接双击appium gui图标(如下图): 2、点击右上角的启动按钮,启动日志如下: 八、 运行测试案例: 1、在eclipse中,项目右键>【Run As】>【JUnit Test】,运行过程截图如下: 2、运行日志: > Checking if an update is available > Update not available > Starting Node Server > warn: Appium support for versions of node < 0.12 has been deprecated and will be removed in a future version. Please upgrade! > info: Welcome to Appium v1.4.0 (REV 8f63e2f91ef7907aed8bda763f4e5ca08e86970a) > info: Appium REST http interface listener started on 127.0.0.1:4723 > info: [debug] Non-default server args: {"app":"F:\\workspace\\AppiumDemo\\apps\\ContactManager.apk","address":"127.0.0.1","logNoColors":true,"deviceName":"test","platformName":"Android","platformVersion":"18","automationName":"Appium"} > info: Console LogLevel: debug > info: --> POST /wd/hub/session {"desiredCapabilities":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"}} > info: Client User-Agent string: Apache-HttpClient/4.3.4 (java 1.5) > info: [debug] Using local app from desired caps: F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] Creating new appium session 97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 > info: Starting android appium > info: [debug] Getting Java version > info: Java version is: 1.7.0_51 > info: [debug] Checking whether adb is present > info: [debug] Using adb from D:\android-sdk\sdk\platform-tools\adb.exe > info: [debug] Set chromedriver binary as: D:\Program Files\Appium\node_modules\appium\build\chromedriver\windows\chromedriver.exe > info: [debug] Using fast reset? true > info: [debug] Preparing device for session > info: [debug] Checking whether app is actually present > info: Retrieving device > info: [debug] Trying to find a connected android device > info: [debug] Getting connected devices... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe devices > info: [debug] 1 device(s) connected > info: Found device emulator-5554 > info: [debug] Setting device id to emulator-5554 > info: [debug] Waiting for device to be ready and to respond to shell commands (timeout = 5) > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 wait-for-device > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "echo 'ready'" > info: [debug] Starting logcat capture > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: Device API level is: 18 > info: [debug] Extracting strings for language: default > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop persist.sys.language" > info: [debug] Current device persist.sys.language: en > info: [debug] java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\appium_apk_tools.jar" "stringsFromApk" "F:\workspace\Appium_demo\apps\ContactManager.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.example.android.contactmanager" en > info: [debug] No strings.xml for language 'en', getting default strings.xml > info: [debug] java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\appium_apk_tools.jar" "stringsFromApk" "F:\workspace\Appium_demo\apps\ContactManager.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.example.android.contactmanager" > info: [debug] Reading strings from converted strings.json > info: [debug] Setting language to default > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 push "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\com.example.android.contactmanager\\strings.json" /data/local/tmp > info: [debug] Checking whether aapt is present > info: [debug] Using aapt from D:\android-sdk\sdk\build-tools\android-4.3\aapt.exe > info: [debug] Retrieving process from manifest. > info: [debug] executing cmd: D:\android-sdk\sdk\build-tools\android-4.3\aapt.exe dump xmltree F:\workspace\Appium_demo\apps\ContactManager.apk AndroidManifest.xml > info: [debug] Set app process to: com.example.android.contactmanager > info: [debug] Not uninstalling app since server not started with --full-reset > info: [debug] Checking app cert for F:\workspace\Appium_demo\apps\ContactManager.apk. > info: [debug] executing cmd: java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\verify.jar" F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] App already signed. > info: [debug] Zip-aligning F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] Checking whether zipalign is present > info: [debug] Using zipalign from D:\android-sdk\sdk\tools\zipalign.exe > info: [debug] Zip-aligning apk. > info: [debug] executing cmd: D:\android-sdk\sdk\tools\zipalign.exe -f 4 F:\workspace\Appium_demo\apps\ContactManager.apk C:\Users\ADMINI~1\AppData\Local\Temp\11572-12744-gdxu1q\appium.tmp > info: [debug] MD5 for app is b2d2916bb5388e1dc281ec3e71ef1234 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "ls /data/local/tmp/b2d2916bb5388e1dc281ec3e71ef1234.apk" > info: [debug] Getting install status for com.example.android.contactmanager > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "pm list packages -3 com.example.android.contactmanager" > info: [debug] App is installed > info: App is already installed, resetting app > info: [debug] Running fast reset (stop and clear) > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "am force-stop com.example.android.contactmanager" > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "pm clear com.example.android.contactmanager" > info: [debug] Forwarding system:4724 to device:4724 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 forward tcp:4724 tcp:4724 > info: [debug] Pushing appium bootstrap to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 push "D:\\Program Files\\Appium\\node_modules\\appium\\build\\android_bootstrap\\AppiumBootstrap.jar" /data/local/tmp/ > info: [debug] Pushing settings apk to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 install "D:\Program Files\Appium\node_modules\appium\build\settings_apk\settings_apk-debug.apk" > info: [debug] Pushing unlock helper app to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 install "D:\Program Files\Appium\node_modules\appium\build\unlock_apk\unlock_apk-debug.apk" > info: Starting App > info: [debug] Attempting to kill all 'uiautomator' processes > info: [debug] Getting all processes with 'uiautomator' > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "ps 'uiautomator'" > info: [debug] No matching processes found > info: [debug] Running bootstrap > info: [debug] spawning: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e pkg com.example.android.contactmanager -e disableAndroidWatchers false > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream= > info: [debug] [UIAUTOMATOR STDOUT] io.appium.android.bootstrap.Bootstrap: > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 1 > info: [debug] [BOOTSTRAP] [debug] Socket opened on port 4724 > info: [debug] [BOOTSTRAP] [debug] Appium Socket Server Ready > info: [debug] [BOOTSTRAP] [debug] Loading json... > info: [debug] Waking up device if it's not alive > info: [debug] Pushing command to appium work queue: ["wake",{}] > info: [debug] [BOOTSTRAP] [debug] json loading complete. > info: [debug] [BOOTSTRAP] [debug] Registered crash watchers. > info: [debug] [BOOTSTRAP] [debug] Client connected > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"wake","params":{}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: wake > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window" > info: [debug] Screen already unlocked, continuing. > info: [debug] Pushing command to appium work queue: ["getDataDir",{}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"getDataDir","params":{}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: getDataDir > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"\/data","status":0} > info: [debug] dataDir set to: /data > info: [debug] Pushing command to appium work queue: ["compressedLayoutHierarchy",{"compressLayout":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"compressedLayoutHierarchy","params":{"compressLayout":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: compressedLayoutHierarchy > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":false,"status":0} > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n com.example.android.contactmanager/.ContactManager" > info: [debug] Waiting for pkg "com.example.android.contactmanager" and activity ".ContactManager" to be focused > info: [debug] Getting focused package and activity > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window windows" > info: [debug] Getting focused package and activity > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window windows" > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.release" > info: [debug] Device is at release version 4.3 > info: [debug] Device launched! Ready for commands > info: [debug] Setting command timeout to the default of 60 secs > info: [debug] Appium session started with sessionId 97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 > info: <-- POST /wd/hub/session 303 54844.194 ms - 74 > info: --> GET /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 {} > info: [debug] Responding to client with success: {"status":0,"value":{"platform":"LINUX","browserName":"","platformVersion":"4.3","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"},"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","deviceName":"emulator-5554","platformName":"Android","appActivity":".ContactManager","appPackage":"com.example.android.contactmanager"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- GET /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 200 10.271 ms - 758 {"status":0,"value":{"platform":"LINUX","browserName":"","platformVersion":"4.3","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"},"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","deviceName":"emulator-5554","platformName":"Android","appActivity":".ContactManager","appPackage":"com.example.android.contactmanager"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element {"using":"name","value":"Add Contact"} > warn: [DEPRECATED] The name locator strategy has been deprecated and will be removed. Please use the accessibility id locator strategy instead. > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"name","selector":"Add Contact","context":"","multiple":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"name","selector":"Add Contact","context":"","multiple":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding Add Contact using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Add Contact, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"ELEMENT":"1"},"status":0} > info: [debug] Responding to client with success: {"status":0,"value":{"ELEMENT":"1"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element 200 5585.076 ms - 87 {"status":0,"value":{"ELEMENT":"1"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/1/click {"id":"1"} > info: [debug] Pushing command to appium work queue: ["element:click",{"elementId":"1"}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:click","params":{"elementId":"1"}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: click > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/1/click 200 3611.421 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/elements {"using":"class name","value":"android.widget.EditText"} > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"class name","selector":"android.widget.EditText","context":"","multiple":true}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"class name","selector":"android.widget.EditText","context":"","multiple":true}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding android.widget.EditText using CLASS_NAME with the contextId: multiple: true > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying. > info: [debug] [BOOTSTRAP] [debug] Finding android.widget.EditText using CLASS_NAME with the contextId: multiple: true > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (1) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=1] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (2) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=2] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (3) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=3] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"status":0} > info: [debug] Responding to client with success: {"status":0,"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/elements 200 7287.293 ms - 121 {"status":0,"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/2/value {"id":"2","value":["Some Name"]} > info: [debug] Pushing command to appium work queue: ["element:setText",{"elementId":"2","text":"Some Name","replace":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:setText","params":{"elementId":"2","text":"Some Name","replace":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: setText > info: [debug] [BOOTSTRAP] [debug] Using element passed in. > info: [debug] [BOOTSTRAP] [debug] Attempting to clear using UiObject.clearText(). > info: [debug] [BOOTSTRAP] [debug] Sending plain text to element: Some Name > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/2/value 200 16926.651 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/4/value {"id":"4","value":["Some@example.com"]} > info: [debug] Pushing command to appium work queue: ["element:setText",{"elementId":"4","text":"Some@example.com","replace":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:setText","params":{"elementId":"4","text":"Some@example.com","replace":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: setText > info: [debug] [BOOTSTRAP] [debug] Using element passed in. > info: [debug] [BOOTSTRAP] [debug] Attempting to clear using UiObject.clearText(). > info: [debug] [BOOTSTRAP] [debug] Sending plain text to element: Some@example.com > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/4/value 200 21149.764 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/touch/perform {"actions":[{"action":"press","options":{"x":100,"y":500}},{"action":"wait","options":{"ms":2}},{"action":"moveTo","options":{"x":100,"y":100}},{"action":"release","options":{}}]} > info: [debug] Pushing command to appium work queue: ["swipe",{"startX":100,"startY":500,"endX":100,"endY":100,"steps":0}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"swipe","params":{"startX":100,"startY":500,"endX":100,"endY":100,"steps":0}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: swipe > info: [debug] [BOOTSTRAP] [debug] Display bounds: [0,0][480,800] > info: [debug] [BOOTSTRAP] [debug] Display bounds: [0,0][480,800] > info: [debug] [BOOTSTRAP] [debug] Swiping from [x=100.0, y=500.0] to [x=100.0, y=100.0] with steps: 0 > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/touch/perform 200 903.431 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element {"using":"name","value":"Save"} > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"name","selector":"Save","context":"","multiple":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"name","selector":"Save","context":"","multiple":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding Save using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[TEXT=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying. > info: [debug] [BOOTSTRAP] [debug] Finding Save using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[TEXT=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"No element found","status":7} > info: [debug] Condition unmet after 7910ms. Timing out. > info: [debug] Responding to client with error: {"status":7,"value":{"message":"An element could not be located on the page using the given search parameters.","origValue":"No element found"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element 500 7913.313 ms - 195 > info: --> DELETE /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 {} > info: Shutting down appium session > info: [debug] Pressing the HOME button > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "input keyevent 3" > info: [debug] Stopping logcat capture > info: [debug] Logcat terminated with code null, signal SIGTERM > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"shutdown"} > info: [debug] [BOOTSTRAP] [debug] Got command of type SHUTDOWN > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"OK, shutting down","status":0} > info: [debug] Sent shutdown command, waiting for UiAutomator to stop... > info: [debug] [BOOTSTRAP] [debug] Closed client connection > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=. > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 0 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream= > info: [debug] [UIAUTOMATOR STDOUT] Test results for WatcherResultPrinter=. > info: [debug] [UIAUTOMATOR STDOUT] Time: 89.301 > info: [debug] [UIAUTOMATOR STDOUT] OK (1 test) > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: -1 > info: [debug] UiAutomator shut down normally > info: [debug] Cleaning up android objects > info: [debug] Cleaning up appium session > info: [debug] Responding to client with success: {"status":0,"value":null,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- DELETE /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 200 8799.959 ms - 76 {"status":0,"value":null,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} 参考:http://blog.csdn.net/jlminghui/article/details/41121479 本文转自贺满博客园博客,原文链接:http://www.cnblogs.com/puresoul/p/4696825.html,如需转载请自行联系原作者。

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

Android -- NDK开发入门

第一步,建立一个普通的Android项目HelloNDK,然后在与src同一级的目录下新建一个jni目录; 第二步,在jni目录下新建一个hello_ndk.c文件,代码如下: #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <jni.h> #include <android/log.h> /********获取字符串************* */ jstring Java_com_example_hellondk_MainActivity_readJNIString( JNIEnv* env, jobject obj) { return (*env)->NewStringUTF(env, "Hello from JNI --- 22222 !"); } 说明如下: Java_com_example_hellondk_MainActivity_readJNIString // 方法名,由三部分组成,Java + [com_example_hellondk_HelloNDKActivity](包名+activity名) + [readJNIString](在java代码中调用的方法名) (*env)->NewStringUTF(env, "Hello from JNI --- 22222 !"); //在java中接收的返回值,不能直接return,一定要调用(*env)->NewStringUTF()这个方法返回 第三步,在jni目录下新建一个Android.mk文件,代码如下: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello_ndk LOCAL_SRC_FILES := hello_ndk.c LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY) 说明如下: LOCAL_MODULE := hello_ndk //这个与生成.so文件名有关,和导入Native Support的.so文件有关 LOCAL_SRC_FILES := hello_ndk.c //这个是读取相关的C文件名 第四步,配置android项目的native support,选中项目右键Android Tools--Add Native Support, 打开Add Android Native Support对话框,输入第三步中配置的LOACL_MODULE的值,如下图: 第五步,修改MainActivity.java文件,代码如下: package com.example.hellondk; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.TextView; public class MainActivity extends Activity { TextView mTestTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTestTv = (TextView)findViewById(R.id.test_tv); mTestTv.setText(readJNIString()); } private native String readJNIString(); static { System.loadLibrary("hello_ndk");//引入hello_ndk.so } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 说明如下: 项目运行的时候首先会执行static里面的方法,引入hello_ndk.so,然后执行onCreate里的方法,读取C文件里的方法获取返回值并显示在TextView控件上。 第六步,运行Android Application项目,程序会首先生成.so文件,成功后继续运行android项目,生成.so的过程如下: 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3908734.html,如需转载请自行联系原作者

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

物联网入门指南

智能门锁、智能温控、智能汽车……你可能最近经常听到这些名词,今后他们会出现的更频繁。但是这些到底是什么呢?是什么让他们那么智能呢? 这些设备被称为物联网(loT),简单来说,物联网是让日常物品连接到互联网并且互相通讯,目的是让用户有更智能、高效的体验。最近的一些例子包括NEST烟雾探测器和August门锁。 但是与任何新技术相比,物联网可能会给消费者带来疑惑和恐惧,尤其是越来越多的公司加入到这场标准、安全、隐私之战的漩涡中。我编写了一个常见问题清单,让大家更容易明白物联网怎么工作,这些设备在现实生活中怎么用,它带来的一些问题和面临的一些挑战。 跟我对话的人物来自于物联网产品行业和行业标准企业,包括苹果,SmartThings,物联网联盟,AllSeen联盟,the Open Interconnect联盟和the Thread Group。 到底什么是物联网? “物联网”这个流行词背后的思路是让无生命的物体带有内置的无线连接,让他们可以监控,控制,并通过移动应用程序连接到互联网上。 连接对象的类型涵盖范围广泛,从穿戴物到灯泡家电(如咖啡机,洗衣机,甚至你的车),真的是任何东西。它也被应用到像医疗保健行业和交通系统这种垂直市场上。 行,我觉得我懂了,但是你能给我个例子吗,它现在是怎么被用在现实生活中,又是怎么让我的生活更便利的呢? 其中一个广为人知的例子是NEST温控器。这个通过wifi连接的温控器让你可以通过你的手机远程调节温度,并且有自己的记忆模式去创造一个温度设定表。 这个的潜在价值就在于帮你节省费用,如果出门前忘记关空调的话,你可以远程关闭它。这也是一个便利的因素,NEST可以记住你喜欢在睡觉时调低温度,可以在你设定的时间自动调低。 另一家公司是在八月份被三星收购的SmartThings,提供各种传感器和智能家居套件,可以监测谁进出你的房子,可以提醒你潜在的漏水危机,让业主安心。 随着物联网的扩大,产品日益成熟,我们可以设想这样一个场景:你的健身追踪器发现你已经睡着了,然后自动关闭电视和灯光。或者,出门前,你的车可以查看工作日程,并自动提供最佳路线去赴会,或者在你要迟到的时候发送一条简讯给有关各方。 从大的方面来说,城市可以利用它来监测数不胜数的停车位、空气、水质和交通。 物联网是怎么工作的? 首先,基础上来说,各种无线电让这些设备之间的连接和联网成为可能。包括我们更熟悉的wifi、低功耗蓝牙、NFC、RFID,还有一些你可能没有听说过的,像 ZigBee, Z-Wave和6LoWPAN。 然后是这些设备本身,不管是运动监测器、门锁或是灯泡,还有可能是中心轮毂,会允许不同的设备彼此连接。 最后,还有云服务,它使数据得以收集和分析,所以我们才能看到到底发生了什么,也才能通过手机应用程序来控制。 正在研究物联网的是些什么公司? 在这一点上,更简单的问题应该是说谁没有在研究物联网产品。知名的大公司像是三星、LG、苹果、google、Lowe’s、飞利浦都致力于这方面,和一些小公司、初创公司一样。Gartner预测,49亿物联网设备将在今年投入使用,到2020年这个数字将达到250亿。 那么,是不是所有的设备都能相互通讯呢? 这就有一点复杂了。因为很多公司都在研发不同的产品、技术、平台,让所有设备彼此都能通讯就不再那么简单了,无缝整体兼容应该是不会实现的。 一些组织正在努力搭建一个开放式标准,让不同产品保持互通性。其中包括the AllSeen Alliance,它的成员有高通、LG、微软、松下、索尼;还有 the Open Interconnect Consortium,包括英特尔、思科、通用、三星、惠普。 虽然他们的最终目标是一致的,但是依然有一些分歧需要克服。例如说,OIC表示 the AllSeen Alliance在安全和知识产权保护方面做的还不够。但是the AllSeen Alliance说因为他们有超过110家的成员,所以这不会是一个问题。 现在我们还不清楚这场标准之战最后会如何结束,但是我们能想到的是,最后一定会有三到四个不同的标准,而不是一家独大的局面(想想看IOS和Android)。 同时,对于消费者来说,解决这些问题的办法最好是选择一个支持多种无线电技术的设备,像是SmartThings提供的一样。 看上去这些设备会手机很多数据。我应该为隐私和安全担心吗? 智能家电、联网汽车、可穿戴设备收集的大量数据不免让人们开始担心起安全问题,他们恐惧这些个人数据会落入不法分子手中。接入点数量的增加同样带来了安全隐患。 美国联邦贸易委员会已经表示了关注,并且建议企业采取多种防护措施来保护消费者信息安全。然而委员会并没有权利强制执行物联网设备的相关规定,所以还不清楚会有多少企业听取他的意见。 很多公司都说保障安全和隐私是他们的重中之重。例如,苹果公司要求在其HomeKit平台开发产品时,必须有点对点加密、认证和隐私权政策。他们还承诺说不会从HomeKit平台附件中收集用户的任何数据。 我已经充分的了解了物联网,现在是买入的好时机了吗? 虽然物联网已经发展了很多年,但是现在刚开始进入我们的消费领域,类别也尚未成熟。不过也有好的产品出现。如果你现在想要购买,就像你的任何考虑一样,买你信任的公司的产品,确保你能得到一个真正实际解决你问题的方案。毕竟确保你的孩子从学校安全到家是一回事,但是在一台联网的crockpot上烤面包又是另一回事。 作者:何妍 来源:51CTO

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

Spring Boot 快速入门

Spring Boot官方介绍 Spring Boot makes it easy to create Spring-powered, production-grade applications and services with absolute minimum fuss. It takes an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need. You can use Spring Boot to create stand-alone Java applications that can be started using java -jar or more traditional WAR deployments. We also provide a command line tool that runs spring scripts. Spring Boot主要优点: 创建独立的Spring应用程序 嵌入的Tomcat,无需部署WAR文件 简化Maven配置 自动配置Spring 提供生产就绪型功能,如指标,健康检查和外部配置 无需编写繁琐的XML配置 快速创建Spring Boot项目 访问:http://start.spring.io/ 选择构建工具Maven Project、Spring Boot版本1.5.4以及一些工程基本信息 点击Generate Project下载项目压缩包 解压项目包,并用IDE以Maven项目导入 项目结构 pom.xml <![CDATA[ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-boot-sample</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-sample</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--核心模块,包括自动配置支持、日志和YAML--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--热启动--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <!--测试模块,包括JUnit、Hamcrest、Mockito--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <!-- 设定Maven仓库 --> <repositories> <repository> <id>maven-aliyun</id> <name>maven-aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </repository> </repositories> <!-- 设定plugin仓库 --> <pluginRepositories> <pluginRepository> <id>maven-aliyun</id> <name>maven-aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </pluginRepository> </pluginRepositories> </project> ]]> SpringBootSampleApplication.java @SpringBootApplication public class SpringBootSampleApplication { public static void main(String[] args) { SpringApplication.run(SpringBootSampleApplication.class, args); } } SampleController.java class SampleController { @RequestMapping(value = "/hello") String hello() { return "hello world!"; } } SpringBootSampleApplicationTests @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc public class SpringBootSampleApplicationTests { @Autowired private MockMvc mvc; @Test public void contextLoads() { try{ URI uri = new URI("/hello"); MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON)) .andReturn(); String context = mvcResult.getResponse().getContentAsString(); System.out.println(context); }catch (Exception e){ e.printStackTrace(); } } } application.properties server.port=8000 #指定程序运行端口 大功告成!!!运行SpringBootSampleApplication的main方法SpringBoot即可启动起来~浏览器访问http://localhost:8000/hello 运行测试类 欢迎支持

资源下载

更多资源
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应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册