首页 文章 精选 留言 我的

精选列表

搜索[GA4集成],共10008篇文章
优秀的个人博客,低调大师

SpringBoot之集成Spring AOP

在开始之前,我们先把需要的jar包添加到工程里。新增Maven依赖如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 接下来,我们进入正题。这里的涉及的通知类型有:前置通知、后置最终通知、后置返回通知、后置异常通知、环绕通知,下面我们就具体的来看一下怎么在SpringBoot中添加这些通知。 首先我们先创建一个Aspect切面类: @Component @Aspect publicclassWebControllerAop{ } 指定切点: //匹配com.zkn.learnspringboot.web.controller包及其子包下的所有类的所有方法 @Pointcut("execution(*com.zkn.learnspringboot.web.controller..*.*(..))") publicvoidexecuteService(){ } 接着我们再创建一个Controller请求处理类: packagecom.zkn.learnspringboot.web.controller; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; /** *Createdbyzknon2016/11/19. */ @RestController @RequestMapping("/aop") publicclassAopTestController{ } 前置通知 配置前置通知: /** *前置通知,方法调用前被调用 *@paramjoinPoint */ @Before("executeService()") publicvoiddoBeforeAdvice(JoinPointjoinPoint){ System.out.println("我是前置通知!!!"); //获取目标方法的参数信息 Object[]obj=joinPoint.getArgs(); //AOP代理类的信息 joinPoint.getThis(); //代理的目标对象 joinPoint.getTarget(); //用的最多通知的签名 Signaturesignature=joinPoint.getSignature(); //代理的是哪一个方法 System.out.println(signature.getName()); //AOP代理类的名字 System.out.println(signature.getDeclaringTypeName()); //AOP代理类的类(class)信息 signature.getDeclaringType(); //获取RequestAttributes RequestAttributesrequestAttributes=RequestContextHolder.getRequestAttributes(); //从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequestrequest=(HttpServletRequest)requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); //如果要获取Session信息的话,可以这样写: //HttpSessionsession=(HttpSession)requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION); Enumeration<String>enumeration=request.getParameterNames(); Map<String,String>parameterMap=Maps.newHashMap(); while(enumeration.hasMoreElements()){ Stringparameter=enumeration.nextElement(); parameterMap.put(parameter,request.getParameter(parameter)); } Stringstr=JSON.toJSONString(parameterMap); if(obj.length>0){ System.out.println("请求的参数信息为:"+str); } } 注意:这里用到了JoinPoint和RequestContextHolder。通过JoinPoint可以获得通知的签名信息,如目标方法名、目标方法参数信息等。通过RequestContextHolder来获取请求信息,Session信息。 接下来我们在Controller类里添加一个请求处理方法来测试一下前置通知: @RequestMapping("/testBeforeService.do") publicStringtestBeforeService(Stringkey,Stringvalue){ return"key="+key+"value="+value; } 前置通知拦截结果如下所示: 后置返回通知 配置后置返回通知的代码如下: /** *后置返回通知 *这里需要注意的是: *如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息 *如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数 *returning限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值 *@paramjoinPoint *@paramkeys */ @AfterReturning(value="execution(*com.zkn.learnspringboot.web.controller..*.*(..))",returning="keys") publicvoiddoAfterReturningAdvice1(JoinPointjoinPoint,Objectkeys){ System.out.println("第一个后置返回通知的返回值:"+keys); } @AfterReturning(value="execution(*com.zkn.learnspringboot.web.controller..*.*(..))",returning="keys",argNames="keys") publicvoiddoAfterReturningAdvice2(Stringkeys){ System.out.println("第二个后置返回通知的返回值:"+keys); } Controller里添加响应的请求处理信息来测试后置返回通知: @RequestMapping("/testAfterReturning.do") publicStringtestAfterReturning(Stringkey){ return"key=:"+key; } @RequestMapping("/testAfterReturning01.do") publicIntegertestAfterReturning01(Integerkey){ returnkey; } 当发送请求为:http://localhost:8001/aop/testAfterReturning.do?key=testsss&value=855sss时,处理结果如图所示: 当发送请求为:http://localhost:8001/aop/testAfterReturning01.do?key=55553&value=855sss时,处理结果如图所示: 后置异常通知 后置异常通知的配置方式如下: /** *后置异常通知 *定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法; *throwing限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行, *对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。 *@paramjoinPoint *@paramexception */ @AfterThrowing(value="executeService()",throwing="exception") publicvoiddoAfterThrowingAdvice(JoinPointjoinPoint,Throwableexception){ //目标方法名: System.out.println(joinPoint.getSignature().getName()); if(exceptioninstanceofNullPointerException){ System.out.println("发生了空指针异常!!!!!"); } } Controller里配置响应的请求处理类: @RequestMapping("/testAfterThrowing.do") publicStringtestAfterThrowing(Stringkey){ thrownewNullPointerException(); } 后置异常通知方法的处理结果如下所示: 后置最终通知 后置最终通知的配置方式如下: /** *后置最终通知(目标方法只要执行完了就会执行后置通知方法) *@paramjoinPoint */ @After("executeService()") publicvoiddoAfterAdvice(JoinPointjoinPoint){ System.out.println("后置通知执行了!!!!"); } Controller类配置相应的请求处理类: @RequestMapping("/testAfter.do") publicStringtestAfter(Stringkey){ thrownewNullPointerException(); } @RequestMapping("/testAfter02.do") publicStringtestAfter02(Stringkey){ returnkey; } 当发送请求为:http://localhost:8001/aop/testAfter.do?key=55553&value=855sss 当发送请求为:http://localhost:8001/aop/testAfter02.do?key=55553&value=855sss 环绕通知 环绕通知的配置方式如下: /** *环绕通知: *环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。 *环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型 */ @Around("execution(*com.zkn.learnspringboot.web.controller..*.testAround*(..))") publicObjectdoAroundAdvice(ProceedingJoinPointproceedingJoinPoint){ System.out.println("环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName()); try{ Objectobj=proceedingJoinPoint.proceed(); returnobj; }catch(Throwablethrowable){ throwable.printStackTrace(); } returnnull; } Controller对应的请求处理类如下: @RequestMapping("/testAroundService.do") publicStringtestAroundService(Stringkey){ return"环绕通知:"+key; } 当发送请求为:http://localhost:8001/aop/testAroundService.do?key=55553 当发送请求为:http://localhost:8001/aop/testAfter02.do?key=55553&value=855sss时,不符合环绕通知的切入规则,所以环绕通知不会 执行。 完整的AOP配置代码如下: packagecom.zkn.learnspringboot.aop; importcom.alibaba.fastjson.JSON; importcom.google.common.collect.Maps; importorg.aspectj.lang.JoinPoint; importorg.aspectj.lang.ProceedingJoinPoint; importorg.aspectj.lang.Signature; importorg.aspectj.lang.annotation.*; importorg.springframework.stereotype.Component; importorg.springframework.web.context.request.RequestAttributes; importorg.springframework.web.context.request.RequestContextHolder; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpSession; importjava.util.Enumeration; importjava.util.Map; /** *Createdbyzknon2016/11/18. */ @Component @Aspect publicclassWebControllerAop{ //匹配com.zkn.learnspringboot.web.controller包及其子包下的所有类的所有方法 @Pointcut("execution(*com.zkn.learnspringboot.web.controller..*.*(..))") publicvoidexecuteService(){ } /** *前置通知,方法调用前被调用 *@paramjoinPoint */ @Before("executeService()") publicvoiddoBeforeAdvice(JoinPointjoinPoint){ System.out.println("我是前置通知!!!"); //获取目标方法的参数信息 Object[]obj=joinPoint.getArgs(); //AOP代理类的信息 joinPoint.getThis(); //代理的目标对象 joinPoint.getTarget(); //用的最多通知的签名 Signaturesignature=joinPoint.getSignature(); //代理的是哪一个方法 System.out.println(signature.getName()); //AOP代理类的名字 System.out.println(signature.getDeclaringTypeName()); //AOP代理类的类(class)信息 signature.getDeclaringType(); //获取RequestAttributes RequestAttributesrequestAttributes=RequestContextHolder.getRequestAttributes(); //从获取RequestAttributes中获取HttpServletRequest的信息 HttpServletRequestrequest=(HttpServletRequest)requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); //如果要获取Session信息的话,可以这样写: //HttpSessionsession=(HttpSession)requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION); Enumeration<String>enumeration=request.getParameterNames(); Map<String,String>parameterMap=Maps.newHashMap(); while(enumeration.hasMoreElements()){ Stringparameter=enumeration.nextElement(); parameterMap.put(parameter,request.getParameter(parameter)); } Stringstr=JSON.toJSONString(parameterMap); if(obj.length>0){ System.out.println("请求的参数信息为:"+str); } } /** *后置返回通知 *这里需要注意的是: *如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息 *如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数 *returning限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值 *@paramjoinPoint *@paramkeys */ @AfterReturning(value="execution(*com.zkn.learnspringboot.web.controller..*.*(..))",returning="keys") publicvoiddoAfterReturningAdvice1(JoinPointjoinPoint,Objectkeys){ System.out.println("第一个后置返回通知的返回值:"+keys); } @AfterReturning(value="execution(*com.zkn.learnspringboot.web.controller..*.*(..))",returning="keys",argNames="keys") publicvoiddoAfterReturningAdvice2(Stringkeys){ System.out.println("第二个后置返回通知的返回值:"+keys); } /** *后置异常通知 *定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法; *throwing限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行, *对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。 *@paramjoinPoint *@paramexception */ @AfterThrowing(value="executeService()",throwing="exception") publicvoiddoAfterThrowingAdvice(JoinPointjoinPoint,Throwableexception){ //目标方法名: System.out.println(joinPoint.getSignature().getName()); if(exceptioninstanceofNullPointerException){ System.out.println("发生了空指针异常!!!!!"); } } /** *后置最终通知(目标方法只要执行完了就会执行后置通知方法) *@paramjoinPoint */ @After("executeService()") publicvoiddoAfterAdvice(JoinPointjoinPoint){ System.out.println("后置通知执行了!!!!"); } /** *环绕通知: *环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。 *环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型 */ @Around("execution(*com.zkn.learnspringboot.web.controller..*.testAround*(..))") publicObjectdoAroundAdvice(ProceedingJoinPointproceedingJoinPoint){ System.out.println("环绕通知的目标方法名:"+proceedingJoinPoint.getSignature().getName()); try{//obj之前可以写目标方法执行前的逻辑 Objectobj=proceedingJoinPoint.proceed();//调用执行目标方法 returnobj; }catch(Throwablethrowable){ throwable.printStackTrace(); } returnnull; } } 完整的Controller类代码如下: packagecom.zkn.learnspringboot.web.controller; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; /** *Createdbyzknon2016/11/19. */ @RestController @RequestMapping("/aop") publicclassAopTestController{ @RequestMapping("/testBeforeService.do") publicStringtestBeforeService(Stringkey,Stringvalue){ return"key="+key+"value="+value; } @RequestMapping("/testAfterReturning.do") publicStringtestAfterReturning(Stringkey){ return"key=:"+key; } @RequestMapping("/testAfterReturning01.do") publicIntegertestAfterReturning01(Integerkey){ returnkey; } @RequestMapping("/testAfterThrowing.do") publicStringtestAfterThrowing(Stringkey){ thrownewNullPointerException(); } @RequestMapping("/testAfter.do") publicStringtestAfter(Stringkey){ thrownewNullPointerException(); } @RequestMapping("/testAfter02.do") publicStringtestAfter02(Stringkey){ returnkey; } @RequestMapping("/testAroundService.do") publicStringtestAroundService(Stringkey){ return"环绕通知:"+key; } } 本文转自:http://lib.csdn.net/article/microservice/60453?knId=1899

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

MyEclipse离线集成Maven插件

MyEclipse自带有Maven4MyEclipse插件,如果没有可以在线和离线安装的方式,在线安装由于网络问题或者插件下载地址的问题导致安装失败,现在给大家介绍离线安装的方式。 1、Maven插件下载地址:http://pan.baidu.com/s/1mi94Efe 2、在MyEclipse 安装目录下新建maven文件夹,比如我的安装目录为:C:\MyEclipseSpr10.6\MyEclipse for Spring 10\dropins\目录下新建maven文件夹,然后解压下载到Maven插件,把目录下的features文件夹和plugins文件夹拷贝到新建的maven目录下。 3、在MyEclipse安装目录下的dropins目录新建txt文本,并重命名为maven.link。 4、编辑maven.link文件,输入path=C:\MyEclipseSpr10.6\MyEclipse for Spring 10\dropins\maven。 5、重启MyEclipse,查看MyEclipse工具栏Window/Preferences下就会出现Maven的选项,到此为止你已成功安装maven插件。

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

C#接口,类,集成

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace Demo{ public abstract class MyBase { } internal class MyClass : MyBase { } public interface IMyBaseInterface { } internal interface IMyBaseInterface2 { } internal interface IMyInterface : IMyBaseInterface,IMyBaseInterface2 { } internal sealed class MyComplexClass : MyClass,IMyInterface { } class Program { static void Main(string[] args) { MyComplexClass myObj = new MyComplexClass(); Console.WriteLine(myObj.ToString()); Console.ReadKey(); } } }一个namespace可以定义多种类与接口,有意思。本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/p/6758409.html,如需转载请自行联系原作者

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

iOS Sonar集成流程详解

所有文章目录:http://my.oschina.net/ChenTF/blog/677112 本篇文章地址:http://my.oschina.net/ChenTF/blog/708646 对您有帮助的话, 还请"赞" 一下哦, 有问题可留言或加QQ群:323276186 关于XCode8的兼容方案, 请看我的这篇文章:https://my.oschina.net/ChenTF/blog/80656 1. Sonar介绍 行业内提到"代码质量管理, 自动化质量管理", 一般指的都是通过Sonar来实现。本文的目标是实现在Sonar上显示出iOS项目, 先看张最终的效果图: 用Sonar能够实现什么? 技术债务(sonar根据"规则"扫描出不符合规则的代码) 覆盖率(单元测试覆盖率) 重复(重复的代码, 有利于提醒封装) 结构 问题1: "规则"指的是什么? 在Sonar工具中配置检测工具(规则), 然后sonar根据规则检测"质量报告文件", 得出问题数目。 比如本文配置的规则是OCLint 问题2: 技术债务的天数怎么得出? 每个规则都有对应的处理时间, 最后:问题类型1数目 * 对应时间 + 问题类型2数目 * 对应时间 +... 得到时间。 2. 概述 Sonar原生并不支持iOS, 所以就需要我们自己按照Sonar原理来安装各个工具, 并将各个工具连接起来, 生成质量结果, 并由Jenkins来实现自动化执行。 但由于涉及到的知识范围很广, 不仅需要iOS开发技术, 还需要运维知识和各个命令工具的使用方法。 而且国内外的资料少的相当可怜, 没有最佳实践, 没有专门的第三方平台, 造成很多东西都是一步步试错出来的, 一步一坎, 所以用了很长时间。 不过最后都将每个工具, 每个步骤打通, 将各个工具连接起来, 整理成.sh脚本和 .properties配置文件, 这样在后续新添项目时会很轻松。 3. 宏观介绍 3.1 配置关系图 3.2 涉及到的知识点 XCTool工具 OClint工具 Gcovr工具 Git, SVN命令 Linux命令 Jenkins工具 Sonar工具 Shell语法 Sonar-runner工具 3.3 关系逻辑讲解 每个项目添加一个配置文件(.properties), 为了在Jenkins上调用命令时能自动填充项目设置; 在Jenkins上安装各个工具(XCTool, OCLint, gcovr, sonar-runner) 与 .sh脚本, Jenkins服务器可以从代码仓库clone下代码, 然后通过.sh脚本与.properties配置文件来调用各个“工具”, 然后每个项目生成对应的“文件”; 在 .sh脚本 最后会通过sonar-runner将生成的 ”文件” 传给Sonar服务器, Sonar服务器以图形化的形式显示出对应的结果。 具体传递给哪个sonar服务器与项目名, 都是在.properties中进行配置 4.环境配置 4.1 基础知识 其实Sonar的展示是将一系列的报告文件转换得到的, 文件又是通过各个工具生成的, 所以需要先安装工具。 涉及到的工具包括(1.xctool 2.oclint, 3.gcovr, 4.sonar-runner), 虽然涉及的工具比较多, 每个用法都可详细的单独讲, 但不建议在开始时就深入了解这些, 本文会将用到的地方进行讲解, 后续深入了解请看给出的推荐资料。 在接下来的步骤中, 需要具备基础的Linuxl知识与Shell知识, 建议有空的话先学学。 Linux教程:http://c.biancheng.net/cpp/html/2726.html Shell教程:http://c.biancheng.net/cpp/view/6994.html 4.2 工具-HomeBrew “gem管理器”, 通过该工具可以安装别的gem工具, 类似cocoapods。 安装方法:http://brew.sh/index_zh-cn.html 详细介绍:https://github.com/Homebrew/brew/blob/master/share/doc/homebrew/README.md#readme 有了此工具后, 以下的工具都可通过该工具来安装, 正确的使用方式是先search 工具, 再install工具 4.3 工具-XCTool 此工具是用来代替XCode在服务器上执行Build, Test等命令, 类似xcodebuild。 安装方法:$brew install xctool 详细介绍:https://github.com/facebook/xctool 4.4 工具-OCLint OCLint是一个静态分析工具, 可以检测OC代码, 发现语法漏洞。用该工具来生成代码质量报告(技术债务)。 安装方式: $brew install Caskroom/cask/oclint 或 $brew tap oclint/formulae $ brew install oclint (不走上面的命令直接install oclint的话, 下载的版本不是最新版, 文档将不能正常生成) 4.5 工具-Gcovr 该工具是用来生成单元测试覆盖率的文档的 安装方式: $brew install gcovr 4.6 环境-JDK 教程:http://jingyan.baidu.com/article/ce09321b7c111f2bff858fea.html 5.Jenkins Jenkins一般被称为"构建器", 说简单点就是 "定时触发 + 配置任务"。Jenkins可以通过协同很多别的工具工作, 本文就是通过.sh(脚本)来协同SVN/Git 与 各个工具, 来生成文件并传给Sonar服务器。 更多Jenkins的知识具体看这两篇教程。 http://www.cnblogs.com/zz0412/p/jenkins02.html http://www.cnblogs.com/horizonli/p/5330073.html 5.1新建一个工程 5.2 代码仓库设置 5.2.1 SVN 关于credential: Jenkins检测到当前服务器访问不了代码仓库时, 会提示你设置权限, 进入Credential, 设置账号密码就可以了。 5.2.2Git方式 git的Credentials设置: 设置好username与private key(能访问git电脑的私钥)就可以了, Passphrase会自动生成。 关于公钥私钥的介绍: 一般的SSH方式是在git服务器的SSH设置里面添加自己当前电脑的公钥(id_rsa.pub)。然后当前电脑访问Git服务器时就能直接访问了。 但Jenkins需要在Git上设置好当前电脑的私钥后, 还需要将当前电脑的私钥(id_rsa)保存在Jenkins配置中。猜测是访问git时是以别的电脑来访问的。 附: Git教程:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 5.3 构建设置 Jenkins支持通过脚本构建, 一般再次设置一些环境与变量, 然后执行脚本。一般此处的设置要结合具体的脚本调用方式来决定, 所以再第六节再详细介绍。 我当前的设置是这样的: 先设置环境变量 跳转到工程根目录下 把脚本copy到当前目录下 执行脚本 5.4 定时构建 可以指定每天几点执行一次, 或每周五执行一次, 当然也可以点击左上角的"立即构建"立即执行。 例: 设置为周一到周五的9点30~9点45之间进行 6.更多说明 6.1 Sonar配置 本项目的配置指导来源于"https://github.com/octo-technology/sonar-objective-c", 后发现教程中的配置不好用, 最后找到这篇Fork的文章"https://github.com/mjdetullio/sonar-objective-c", 最后是按照第二篇的设置进行的。sonar的配置具体看第二篇文章 其实我对Sonar的配置不是很清楚, 先留个坑吧。 只知道最后通过runner-sonar工具将生成的文件传给了Sonar服务器, 至于Sonar的配置参数, 则是从.sonar-project.properties文件里面获取的。 附: Sonar官网:http://www.javatips.net/blog/sonarqube-tutorial Sonar安装:http://www.uml.org.cn/jchgj/201307251.asp 6.2 工程配置 按照教程的指导, 将run-sonar.sh和sonar-project.properties放到根目录下, 修改.properties文件的内容, 然后执行run-sonar.sh就可以了。 我是将.properties随项目走, 因为每个项目的配置不一样, 而run-sonar.sh是固定不变的, 所以放在了Jenkins服务器上, 再执行构建时将其拷贝到当前目录下。 介绍些配置过程中用到的命令, 方便大家: $ ssh 用户名@服务器地址 // 通过bash访问远程服务器 $scp /Users/xxx/Documents/svn/run-sonar.sh pmo-mini@111.222.2.444:~/opt/iosShell/run-sonar.sh // 将本地的sh文件copy到远程服务器对应的位置 $ chmod u=rxw run-sonar.sh // 修改文件权限, 使其为可读可写可执行 6.3 脚本执行流程与生成物介绍 clear ↓ build ↓ test : TEST-report.xml ↓ gcovr : coverage-xxx.xml ↓ oclint : oclint.xml TEST-report.xml 是通过xctool的test命令生成的, 如果生成失败会有2, 3行的默认文本, 这时就可以证明是执行到test时失败了, 建议先用xcode执行测试, 把环境调通了, 更多单元测试文章, 请看我的 "iOS单元测试入门与配置"篇; coverage-XiangMu.xml 是单测覆盖率报告, 如果你的单测覆盖率有误, 看这个文档。走完test后, 在XCode的路径文件下, 会生成项目的覆盖率报告, 然后gcovr命令根据这些报告生成覆盖率报告。 一般覆盖率报告有问题都是test环节有问题 oclint.xml 是技术债务报告, 一般build环节没有问题, 这个报告就没问题。 6.4 脚本分享 因为github上的脚本执行时到test命令就错误了, 所以将我修改后的分享出来。 没有找到能上次文件的地方, 把脚本所以内容全贴出来太浪费地方了, 就分享修改的地方吧, 大家从github上下载, 然后修改吧.. elseecho-n'Running tests using xctool'# runCommand sonar-reports/TEST-report.xml $xctoolCmdPrefix -scheme "$testScheme" -reporter junit GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES test # ctf:这个命令出错, 用下面的命令代替 $xctoolCmdPrefix-scheme"$testScheme"-reporter junit:TEST-report.xml GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES testecho-n'Computing coverage report' # We do it for every xcodeproject (in case of workspaces) 7.成果 7.1 技术债务 不仅可以显示出有多少不符合”规则”的代码片段,还能根据代码仓库的提交历史对应到时谁的问题 7.2 覆盖率 可以检测到单元测试的覆盖范围,监督单元测试覆盖范围。 7.3 重复 检测到相似的代码片段,提醒将常用的功能封装起来,提高重用性。 7.4 结构 项目的文件结构 7.5 代码 7.6 问题 8.未来接入方式与成本 项目中添加.properties配置文件, 修改配置项; 在Jenkins添加对应的项目; 然后? 没有然后了。 本文转自ljianbing51CTO博客,原文链接:http://blog.51cto.com/ljianbing/1930273 ,如需转载请自行联系原作者

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

Docker与OpenStack集成实战

1、计算节点安装Docker root@compute2: ~# apt install docker.io -y 或 root@compute2:~# sh -c "echo deb https://get.docker.io/ubuntu docker main >> /etc/apt/sources.list.d/docker.list" root@compute2:~# apt-get update root@compute2:~# apt-get install lxc-docker root@compute2: ~# apt install docker.io -y 查看当前版本 root@compute2:/var/lib/docker# docker --version Docker version 1.12.0, build 8eab29e root@compute2:~# docker -v Docker version 1.12.0, build 8eab29e root@compute2:~# dpkg -l | grep docker rc docker.io 1.11.2-0ubuntu5~16.04 amd64 Linux container runtime ii lxc-docker 1.9.1 amd64 Linux container runtime ii lxc-docker-1.9.1 1.9.1 amd64 Linux container runtime 查找镜像 root@compute2:~# docker search ubuntu dorapro/ubuntu ubuntu image 0 [OK] konstruktoid/ubuntu Ubuntu base image 0 [OK] uvatbc/ubuntu Ubuntu images with unprivileged user 0 [OK] 2、下载Ubuntu镜像 root@compute2: ~# docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu 2f0243478e1f: Pull complete d8909ae88469: Pull complete 820f09abed29: Pull complete 01193a8f3d88: Pull complete Digest: sha256:8e2324f2288c26e1393b63e680ee7844202391414dbd48497e9a4fd997cd3cbf Status: Downloaded newer image for ubuntu:latest root@compute2:~# docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest bd3d4369aebc 12 days ago 126.6 MB ubuntu-1604-sleepy_kilby latest 94c88d9d0023 3 weeks ago 126.4 MB ubuntu <none> f8d79ba03c00 3 weeks ago 126.4 MB cmer81/centos7-openstack latest 3317e0f4e0fb 7 months ago 322.2 MB 3、启动并登录Docker容器 root@compute2:~# docker run -i -t ubuntu root@c0a0294d98d2:/# cat /etc/issue Ubuntu 16.04.1 LTS \n \l 给容器设置root密码 [root@dfbc7c3db16b /]# passwd root Changing password for user root. New password: Retype new password: passwd: all authentication tokens updated successfully. 设置允许root密码登录 [root@dfbc7c3db16b /]# vi /etc/ssh/sshd_config PermitRootLogin yes PasswordAuthentication yes SSH到容器中 root@compute2:~# ssh 172.17.0.3 root@172.17.0.3's password: [root@dfbc7c3db16b ~]# [root@dfbc7c3db16b ~]# [root@dfbc7c3db16b ~]# [root@dfbc7c3db16b ~]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::42:acff:fe11:3 prefixlen 64 scopeid 0x20<link> ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet) RX packets 434 bytes 52434 (51.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 419 bytes 42782 (41.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@dfbc7c3db16b ~]# 退出Docker容器 root@76da79f898c3:/# exit exit 4、在另一个docker主机查看目前运行的docker进程的ID root@compute2:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a8ffa3d75d46 ubuntu "/bin/bash" 51 seconds ago Exited (127) 42 seconds ago sleepy_kilby aee77e7dec7b ubuntu "/bin/bash" 2 minutes ago Exited (0) 53 seconds ago compassionate_hodgkin c0a0294d98d2 ubuntu "/bin/bash" 47 minutes ago Exited (127) 38 minutes ago ecstatic_ritchie 5、将镜像保存为 root@compute2:~# docker commit a8ffa3d75d46 ubuntu-1604-sleepy_kilby sha256:94c88d9d002364ed5b405357f6910fbc6fdddda917a07f99933a65e66e74fe99 6、将此镜像打包成一个文件 root@compute2:~# docker save ubuntu-1604-sleepy_kilby > /root/ubuntu-1604.tar 7、从终端直接启动容器 root@compute2:~# docker run -i -t -p 50001:22 ubuntu-1604-sleepy_kilby /bin/bash nova-docker方案实践 安装novadocker python-pip 有一个BUG,如果已安装python-pip,先删除, root@compute2:~# apt-get remove python-pip root@compute2:~#apt-get autoremove root@compute2:~# easy_install -U pip root@compute2:~# pip install -e git+https://github.com/stackforge/nova-docker#egg=novadocker root@compute2:~# cd src/novadocker/ root@compute2:~/src/novadocker# python setup.py install 配置NOVA root@compute2:~# vim /etc/nova/nova.conf [DEFAULT] compute_driver = novadocker.virt.docker.DockerDriver 创建/etc/nova/rootwrap.d/dockers.filters # nova-rootwrap command filters for setting up network in the docker driver # This file should be owned by (and only-writeable by) the root user [Filters] # nova/virt/docker/driver.py: 'ln', '-sf', '/var/run/netns/.*' ln: CommandFilter, /bin/ln, root 配置Glance root@controller:/etc/glance# vim glance-api.conf [DEFAULT] container_formats = ami,ari,aki,bare,ovf,docker 下载Docker镜像 查找适用于OpenStack的镜像 root@compute2:~# docker search openstack NAME DESCRIPTION STARS OFFICIAL AUTOMATED krystism/openstack-keystone An easy way to try openstack keystone service 7 [OK] continuse/openstack-controller OpenStack Controller Service for CoreOS 5 [OK] centurylink/openstack-cli-wetty This image provides a Wetty terminal with ... 4 [OK] cmer81/centos7-openstack Centos7 image for openstack-cloudinit 2 [OK] continuse/openstack-nova-docker OpenStack Nova-Docker Service for CoreOS 2 [OK] cosmicq/openstack-nova (project not complete) The Nova (compute) ... 1 [OK] cosmicq/openstack-rabbitmq (project not complete) RabbitMQ (AMQP) ser... 1 [OK] ennweb/openstack-controller OpenStack Controller 1 [OK] cosmicq/openstack-keystone (project not complete) The Keystone (authe... 1 [OK] cosmicq/openstack-mariadb (project not complete) MariaDB and PHPMyAd... 1 [OK] continuse/openstack-network OpenStack Network (Neutron) Service for Co... 1 [OK] continuse/openstack-compute OpenStack Compute Service for CoreOS 1 [OK] krystism/openstack-glance An easy way to try openstack glance service 1 [OK] factual/docker-openstack-database OpenStack Database (MariaDB) 1 [OK] pataquets/openstack-dashboard 0 [OK] colstrom/openstack-cli OpenStack CLI 0 [OK] continuse/openstack-cinder OpenStack Block Storage Service for CoreOS 0 [OK] alvaroaleman/openstack-horizon A simple Docker image for the Openstack Ho... 0 [OK] pataquets/openstack-keystone 0 [OK] pierrezemb/exherbo-openstack Exherbo image generator for OpenStack 0 [OK] factual/docker-openstack-messaging OpenStack Messaging service (RabbitMQ) 0 [OK] ennweb/openstack-compute OpenStack Compute on Docker 0 [OK] anguslees/openstack-tox 0 [OK] gbraad/openstack-client Container with the OpenStack client and 's... 0 [OK] jmcvea/openstack-client OpenStack command line tools 0 [OK] root@compute2:~# root@compute2:~# docker pull cmer81/centos7-openstack Using default tag: latest latest: Pulling from cmer81/centos7-openstack a3ed95caeb02: Pull complete 3286cdf780ef: Pull complete 889e0983d8b8: Pull complete 48ed448d00d6: Pull complete 0ebb5fe0f8ad: Pull complete c93dc6f68ef1: Pull complete cf8e344e8663: Pull complete 9827381c9ae3: Pull complete 8f1f6b35ea96: Pull complete Digest: sha256:84b374fe2a8bf40a8716d79e5ea179b2fb28352e8a18fa49ddda2ab295bebe6e Status: Downloaded newer image for cmer81/centos7-openstack:latest root@compute2:~# docker save cmer81/centos7-openstack | glance --os-image-api-version 1 image-create --is-public=True --container-format=docker --disk-format=raw --name cmer81/centos7-openstack +------------------+--------------------------------------+ | Property | Value | +------------------+--------------------------------------+ | checksum | 114c19e55638a317b837ae73f6c8314c | | container_format | docker | | created_at | 2016-08-17T03:03:22.000000 | | deleted | False | | deleted_at | None | | disk_format | raw | | id | 521f5a87-22cc-4851-a812-dee1b17b5e46 | | is_public | True | | min_disk | 0 | | min_ram | 0 | | name | cmer81/centos7-openstack | | owner | f9027cccf7da4f2399c7fdf32e8776f0 | | protected | False | | size | 334179328 | | status | active | | updated_at | 2016-08-17T03:03:28.000000 | | virtual_size | None | +------------------+--------------------------------------+ 查找ubuntu镜像 root@compute2:~# docker search ubuntu NAME DESCRIPTION STARS OFFICIAL AUTOMATED ubuntu Ubuntu is a Debian-based Linux operating s... 4468 [OK] ubuntu-upstart Upstart is an event-based replacement for ... 65 [OK] rastasheep/ubuntu-sshd Dockerized SSH service, built on top of of... 31 [OK] torusware/speedus-ubuntu Always updated official Ubuntu docker imag... 27 [OK] ubuntu-debootstrap debootstrap --variant=minbase --components... 25 [OK] nickistre/ubuntu-lamp LAMP server on Ubuntu 8 [OK] nuagebec/ubuntu Simple always updated Ubuntu docker images... 7 [OK] nickistre/ubuntu-lamp-wordpress LAMP on Ubuntu with wp-cli installed 6 [OK] nimmis/ubuntu This is a docker images different LTS vers... 5 [OK] jordi/ubuntu Ubuntu Base Image 1 [OK] admiringworm/ubuntu Base ubuntu images based on the official u... 1 [OK] seetheprogress/ubuntu Ubuntu image provided by seetheprogress us... 1 [OK] darksheer/ubuntu Base Ubuntu Image -- Updated hourly 1 [OK] life360/ubuntu Ubuntu is a Debian-based Linux operating s... 0 [OK] datenbetrieb/ubuntu custom flavor of the official ubuntu base ... 0 [OK] konstruktoid/ubuntu Ubuntu base image 0 [OK] lynxtp/ubuntu https://github.com/lynxtp/docker-ubuntu 0 [OK] esycat/ubuntu Ubuntu LTS 0 [OK] widerplan/ubuntu Our basic Ubuntu images. 0 [OK] croscon/ubuntu Crosconized Ubuntu 0 [OK] teamrock/ubuntu TeamRock's Ubuntu image configured with AW... 0 [OK] smartentry/ubuntu ubuntu with smartentry 0 [OK] ustclug/ubuntu ubuntu image for docker with USTC mirror 0 [OK] dorapro/ubuntu ubuntu image 0 [OK] webhippie/ubuntu Docker images for ubuntu 0 [OK] 下载镜像 root@compute2:~# docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu Digest: sha256:8e2324f2288c26e1393b63e680ee7844202391414dbd48497e9a4fd997cd3cbf Status: Image is up to date for ubuntu:latest 把镜像上传到Glance中 root@compute2:~# docker save ubuntu | glance image-create --container-format=docker --disk-format=raw --name ubuntu-docer +------------------+--------------------------------------+ | Property | Value | +------------------+--------------------------------------+ | checksum | 364a6b81f4a3f5fb5c4a0e1d62395322 | | container_format | docker | | created_at | 2016-08-17T02:46:58Z | | disk_format | raw | | id | e2616723-b55d-48a6-9548-606f0da7dddb | | min_disk | 0 | | min_ram | 0 | | name | ubuntu-docer | | owner | f9027cccf7da4f2399c7fdf32e8776f0 | | protected | False | | size | 132096512 | | status | active | | tags | [] | | updated_at | 2016-08-17T02:46:59Z | | virtual_size | None | | visibility | private | +------------------+--------------------------------------+ 、 root@compute2:~# nova image-list +--------------------------------------+-----------------------------------------+--------+--------+ | ID | Name | Status | Server | +--------------------------------------+-----------------------------------------+--------+--------+ | 96872d33-73a1-4e1d-bc9e-5b4206a258af | CentOS-7-x86_64-GenericCloud | ACTIVE | | | c8d224af-b3ed-42be-a29b-ea7295abf932 | Ubuntu16.04-server-clouding-powerpc64el | ACTIVE | | | e9b86672-f9d2-48f3-b57f-0320fc4a048f | Ubuntu16.04-xenial-server-cloud-amd64 | ACTIVE | | | 521f5a87-22cc-4851-a812-dee1b17b5e46 | cmer81/centos7-openstack | ACTIVE | | | e2616723-b55d-48a6-9548-606f0da7dddb | ubuntu-docer | ACTIVE | | | ba5c1506-4389-42b5-acfb-849855b019b5 | ubuntu-server-clouding-amd64 | ACTIVE | | | b2170c9b-41da-4b55-a4ec-88b8b3fc528e | ubuntu1604-server-cloud-ppc64el | ACTIVE | | | c94a41f5-10b2-43f8-ae5d-1c91886f6f94 | windows2012server-clouding | ACTIVE | | +--------------------------------------+-----------------------------------------+--------+--------+ root@compute2:~# nova boot centos7-openstack --image 521f5a87-22cc-4851-a812-dee1b17b5e46 --nic net-id=a969f82e-b4cc-48cf-a04a-64923dc73b4a --flavor 22 --security-groups default --key key +--------------------------------------+-----------------------------------------------------------------+ | Property | Value | +--------------------------------------+-----------------------------------------------------------------+ | OS-DCF:diskConfig | MANUAL | | OS-EXT-AZ:availability_zone | | | OS-EXT-SRV-ATTR:host | - | | OS-EXT-SRV-ATTR:hostname | centos7-openstack | | OS-EXT-SRV-ATTR:hypervisor_hostname | - | | OS-EXT-SRV-ATTR:instance_name | instance-0000070f | | OS-EXT-SRV-ATTR:kernel_id | | | OS-EXT-SRV-ATTR:launch_index | 0 | | OS-EXT-SRV-ATTR:ramdisk_id | | | OS-EXT-SRV-ATTR:reservation_id | r-3euaomoc | | OS-EXT-SRV-ATTR:root_device_name | - | | OS-EXT-SRV-ATTR:user_data | - | | OS-EXT-STS:power_state | 0 | | OS-EXT-STS:task_state | scheduling | | OS-EXT-STS:vm_state | building | | OS-SRV-USG:launched_at | - | | OS-SRV-USG:terminated_at | - | | accessIPv4 | | | accessIPv6 | | | adminPass | KjbkCzV8VVn2 | | config_drive | | | created | 2016-08-17T03:23:21Z | | description | - | | flavor | zoom.medium (22) | | hostId | | | host_status | | | id | 41dad309-eb1a-4445-b1eb-81b87cd34d97 | | image | cmer81/centos7-openstack (521f5a87-22cc-4851-a812-dee1b17b5e46) | | key_name | key | | locked | False | | metadata | {} | | name | centos7-openstack | | os-extended-volumes:volumes_attached | [] | | progress | 0 | | security_groups | default | | status | BUILD | | tenant_id | f9027cccf7da4f2399c7fdf32e8776f0 | | updated | 2016-08-17T03:23:21Z | | user_id | 957ba591d7824e0ab6e54d5c40e6be85 | +--------------------------------------+-----------------------------------------------------------------+ root@compute2:~# nova list +--------------------------------------+-------------------+--------+------------+-------------+-----------------------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+-------------------+--------+------------+-------------+-----------------------------------+ | 41dad309-eb1a-4445-b1eb-81b87cd34d97 | centos7-openstack | ACTIVE | - | Running | private=10.1.1.80, 10.1.1.78 | | 4f6c62b0-3917-4a4c-a017-bc57ff1a7e4d | ubuntu | ACTIVE | - | Running | private=10.1.1.46 本文转自 OpenStack2015 博客,原文链接: http://blog.51cto.com/andyliu/1852267 如需转载请自行联系原作者

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

Mesos和Docker的集成

因为Docker本身想管理整个容器,从chroot、命名空间到整个命名空间的cgroup,它会和默认的Mesos容器发生冲突。因此,Mesos添加了容器机的支持,一种可插拔的机制,让Mesos的容器机子系统可扩展:最初Mesos的基于 LXC/cgroup的容器被引入到容器机API里,Docker是添加的第一个新的容器机,现在也有了全面的文档协议,介绍如何添加新的容器机,比如KVM虚拟机。 使用Docker 为了使用Docker容器机技术,必须将其包含进Mesos slave的命令行里。比如,mesos-slave --containerizers=docker,mesos...允许在该台slave上使用Docker和Mesos容器。 可能还想增加执行器的注册超时时间,这样Mesos不会在容器还在下载的时候就认为容器发生了故障。一开始可以设成五分钟,确保有足够的时间下载Docker镜像。所以,slave命令行类似: mesos-slave --containerizers=docker,mesos \ --executor_registration_timeout=5mins ... 使用带有应用程序的Docker非常简单——一旦启用了对Docker的支持,只需要设置TaskInfo或者ExecutorInfor里的container字段(类型为ContainerInfo)。 令人困惑的是,消息CommandInfo.ContainerInfo并不是正确的消息——需要在带有Docker相关字段的mesos.proto里设置最高级别的ContainerInfo。 要想使用Docker,需要将ContainerInfo里的type设置为DOCKER,并且将docker字段设置到ContainerInfo.Docker消息的一个实例里,该消息的image属性设置为Docker镜像的名称(比如myusername/webapp)。这里可以配置很多Docker参数,比如是使用HOST还是BRIDGE网络,映射使用哪些端口或者额外的Docker命令行参数。如果想让Docker容器使用Dockerfile里指定的docker run ...,还必须将TaskInfo的CommandInfo设置成shell=false。如果设置成shell=true,就需要禁用Dockerfile里的run,指定的command会由sh -c “”来运行。 当启动Docker容器机任务时,slave会首先获取(并且解包)沙箱里所有指定的URI,并且将Docker镜像拉取到本地。然后,slave通过运行docker启动Docker镜像。docker命令的HOME环境变量指向该沙箱,因此可以通过获取到的URI来配置Docker(详见下面的注意事项)。在Docker镜像里可以使用该沙箱,其路径保存在MESOS_SANDBOX环境变量里。最后,Docker的stdout和stderr会被重定向到Mesos沙箱里名为stdout和stderr的文件上。 高级Docker配置必须记住的一点是,Docker容器机总是会尝试从registry里拉取Docker镜像。这意味着无法使用仅在本地安装了的Docker镜像——必须在某个地方部署该镜像。如果想要使用私有registry,可以提供一个.dockercfg文件。该文件由一个URI指定,这样Mesos slave就能够使用其自动获取URL的功能将.dockercfg文件拷贝到Docker进程所使用的HOME目录下。 相同的API也适用于基于Docker的执行器,唯一不同之处在于,执行器代码实际上可以在Docker容器内运行。要实现这一目的,需要完成上文所述的所有事情,但是是在ExecutorInfo消息里,而不是TaskInfo消息里。本文选自《用Mesos框架构建分布式应用》,点此链接可在博文视点官网查看此书。 想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。

资源下载

更多资源
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等操作系统。

WebStorm

WebStorm

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

用户登录
用户注册