Mryqu's Notes


  • 首页

  • 搜索
close

执行Gradle artifactoryPublish任务时碰到HTTP 409 Conflict错误

时间: 2015-07-13   |   分类: Tool   Gradle     |   阅读: 29 字 ~1分钟
这篇博文算是《尝试Artifactory》的姐妹篇。我打算将《尝试Artifactory》中的’libs-snapshot-local’和’libs-snapshot’换成’libs-release-local’和’libs-release’,以便将我的构件发布到发布版仓库里。结果遭遇如下错误: C:\test123\HelloArtifactory>gradlew artifactoryPublish [buildinfo] Not using buildInfo properties file for this build. :generatePomFileForMavenJavaPublication :compileJava 查看Artifactory日志,才知道根本原因在于创建的是SNAPSHOT而libs-release-local只处理发布版构建。The repository ’libs-release-local’ rejected the artifact’libs-release-local:com/yqu/HelloArtifactory/0.1.0-SNAPSHOT/HelloArtifactory-0.1.0-SNAPSHOT.jar’due to its snapshot/release handling policy。 解决方案有如下两种: 修改libs-release-local属性,勾选Handle Snapshots选择框(工作流不正规啦) 将gradle.properties中的version由0.1.0-SNAPSHOT改成0.1.0即可

Gradle Git Plugin介绍

时间: 2015-07-12   |   分类: Tool   Gradle     |   阅读: 60 字 ~1分钟
Grgit和gradle-git Git是一个很流行的分布式版本管理工具。能在构建过程中与Git进行交互,可以提供更强大和更一致的结果。 JGit提供了与Git仓库交互的强大JavaAPI。然而,在Groovy上下本使用它会笨重,需要在所要执行的表达式包一堆换七八糟的东东。Grgit是Andre wOberstar实现的JGit封装器,为基于Groovy的工具与Git仓库交互提供了更简洁流畅的API。 gradle-git同样是由Andrew Oberstar实现的一系列Gradle插件: org.ajoberstar.grgit - 提供一个Grgit实例,允许与Gradle项目所在的Git仓库交互 org.ajoberstar.github-pages - 向Github仓库的gh-pages分支发布文件 org.ajoberstar.release-base -提供用于从项目状态和所在Git仓库推断当前项目版本和创建新版本的通用结构 org.ajoberstar.release-opinion -用于org.ajoberstar.release-base的默认选项,遵从语义版本控制(Semantic Versioning)下面是一个Gradle任务示例,用于从Git仓库克隆项目。 build.gradle buildscript { repositories { mavenCentral() } dependencies { classpath 'org.ajoberstar:gradle-git:1.2.0' } } import org.ajoberstar.gradle.git.tasks.* task cloneGitRepo(type: GitClone) { def destination = file("destination_folder") uri = "your_git_repo_uri" destinationPath = destination bare = false enabled = !destination.exists() //to clone only once } 参考 GitHub:ajoberstar/gradle-git GitHub:ajoberstar/grgit

[Spring Boot] 监控和管理Spring Boot应用

时间: 2015-07-11   |   分类: Service+JavaEE   Spring     |   阅读: 147 字 ~1分钟
本博文在[Spring Boot] Hello Spring LDAP 基础上稍作修改,尝试一下监控和管理Spring Boot应用。 application.properties改动 server.context-path=/HelloSpringLdapOdm server.port=8080 spring.profiles.active=test,dev # spring.dao.exceptiontranslation.enabled=false yqu.ldap.url=ldap://127.0.0.1:18880 yqu.ldap.userDN=uid=admin,ou=system yqu.ldap.password=secret yqu.ldap.base=dc=jayway,dc=se yqu.ldap.clean=true management.port=8081 management.address=127.0.0.1 endpoints.shutdown.enabled=true applicationDefaultJvmArgs: [ "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=55558" ] 测试 autoconfig: Displays an auto-configuration report showing allauto-configuration candidates and the reason why they ‘were’ or‘were not’ applied. beans: Displays a complete list of all the Spring beans in yourapplication. configprops: Displays a collated list of all@ConfigurationProperties. dump: Performs a thread dump. env: Exposes properties from Spring’sConfigurableEnvironment.
阅读全文 »

如何链接并执行GitHub上的JavaScript文件

时间: 2015-07-10   |   分类: FrontEnd     |   阅读: 34 字 ~1分钟
想要玩一下jquery-mockjax,其原始文件为https://raw.githubusercontent.com/jakerella/jquery-mockjax/master/dist/jquery.mockjax.js ,加入我的html文件进行测试。结果却遇到下列问题: Refused to execute script from ... because its MIME type (text/plain) is not executable, and strict MIME type checking is enabled. 查到了StackOverflow上的一个帖子Link and execute external JavaScript file hosted on GitHub ,原来GitHub开始使用X-Content-Type-Options:nosniff以令更多的现代浏览器执行严格MIME类型检查,之后返回原始文件的MIME类型故意让浏览器不能使用。帖子中提到的临时解决方法是将raw.githubusercontent.com替换为rawgit.com。我将上一链接替换成https://rawgit.com/jakerella/jquery-mockjax/master/dist/jquery.mockjax.js ,解决问题!

[Spring Boot] Hello CommandLineRunner

时间: 2015-07-08   |   分类: Service+JavaEE   Spring     |   阅读: 314 字 ~2分钟
通过CommandLineRunner,可在所有Spring Bean和ApplicationContext被创建后执行一些可以访问命令行参数的任务。如想指定多个CommandLineRunnerBean的执行顺序,可以实现org.springframework.core.Ordered接口或添加org.springframework.core.annotation.Order注解。 示例代码 Application.java package com.yqu.cmdlinerunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.Banner; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.DependsOn; import org.springframework.core.annotation.Order; import org.springframework.core.annotation.OrderUtils; import java.util.Arrays; @SpringBootApplication public class Application { private static final Logger log = LoggerFactory.getLogger(Application.class); public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.setWebEnvironment(false); app.setShowBanner(false); app.run(args); } @Bean(name="demo1") @DependsOn("demo2") @Order(8) public CommandLineRunner demo1() { return (args) -> { log.info("demo1:order="+ OrderUtils.getOrder(this.getClass())+ ":args="+Arrays.toString(args)); //log.info(getStacks()); }; } @Bean(name="demo2") @Order(1) public CommandLineRunner demo2() { return (args) -> { log.
阅读全文 »

[Spring Boot] Hello Spring LDAP

时间: 2015-07-06   |   分类: Service+JavaEE   Spring     |   阅读: 396 字 ~2分钟
这个帖子设定了标题后,一直忙于其他事情,拖延了两个月终于能够结贴了。 部分示例代码 LdapConfiugration.java package com.yqu.ldap.odm; import com.yqu.ldap.odm.dao.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.*; import org.springframework.core.env.Environment; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.LdapContextSource; import javax.annotation.PostConstruct; @Configuration @ComponentScan(basePackages={"com.yqu.ldap.odm"}) public class LdapConfiugration { @Autowired private Environment _environment; private static Log log = LogFactory.getLog(LdapConfiugration.class); @PostConstruct private void init() { log.debug("environment: yqu.ldap.url:" + _environment.getProperty("yqu.ldap.url")); log.debug("environment: yqu.ldap.userDN:" + _environment.getProperty("yqu.ldap.userDN")); log.debug("environment: yqu.ldap.password:" + _environment.getProperty("yqu.ldap.password")); log.debug("environment: yqu.ldap.base:" + _environment.getProperty("yqu.ldap.base")); } @Bean(name="ldapContextSource") public LdapContextSource ldapContextSource() { String url = _environment.getProperty("yqu.ldap.url"); String user = _environment.
阅读全文 »

apt-get在基于Ubuntu基础镜像Dockerfile中的常见用法

时间: 2015-07-05   |   分类: Tool   Docker     |   阅读: 91 字 ~1分钟
首先,在Ubuntu的Docker官方镜像中是没有缓存Apt的软件包列表的。因此在做其他任何基础软件的安装前,都需要至少先做一次apt-get update。 有时为了加快apt-get安装软件的速度,还需要修改Apt源的列表文件/etc/apt/sources.list。相应的操作用命令表示如下: # 使用Ubuntu官方的Apt源,也可以根据实际需要修改为国内源的地址 echo "deb http://archive.ubuntu.com/ubuntu trusty main universe\n" > /etc/apt/sources.list echo "deb http://archive.ubuntu.com/ubuntu trusty-updates main universe\n" >> /etc/apt/sources.list 在容器构建时,为了避免使用apt-get install安装基础软件的过程中需要进行的交互操作,使用-y参数来避免安装非必须的文件,从而减小镜像的体积。 apt-get -y --no-install-recommends install 使用apt-get autoremove命令移除为了满足包依赖而安装的、但不再需要的包;使用apt-get clean命令清除所获得包文件的本地仓库。 DEBIAN_FRONTEND这个环境变量,告知操作系统应该从哪儿获得用户输入。如果设置为"noninteractive",你就可以直接运行命令,而无需向用户请求输入(所有操作都是非交互式的)。这在运行apt-get命令的时候格外有用,因为它会不停的提示用户进行到了哪步并且需要不断确认。非交互模式会选择默认的选项并以最快的速度完成构建。请确保只在Dockerfile中调用的RUN命令中设置了该选项,而不是使用ENV命令进行全局的设置。因为ENV命令在整个容器运行过程中都会生效,所以当你通过BASH和容器进行交互时,如果进行了全局设置那就会出问题。 # 正确的做法 - 只为这个命令设置ENV变量 RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3 # 错误地做法 - 为接下来的任何命令都设置ENV变量,包括正在运行地容器 ENV DEBIAN_FRONTEND noninteractive RUN apt-get install -y python3 我的示例如下: FROM ubuntu:trusty MAINTAINER mryqu RUN \ DEBIAN_FRONTEND=noninteractive apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get -y install wget curl && \ DEBIAN_FRONTEND=noninteractive apt-get -y autoremove && \ DEBIAN_FRONTEND=noninteractive apt-get clean 参考 Ubuntu manuals: apt-get man page
阅读全文 »

Docker的镜像存储在哪里和长什么样子

时间: 2015-07-05   |   分类: Tool   Docker     |   阅读: 49 字 ~1分钟
接触docker后,我就有个疑问:我们用docker pull镜像后,该镜像是存储在哪里的?是以一个特俗的二进制类型存储的么?后来阅读了Docker的镜像存储在哪里这篇博文,得以解惑,并进行了验证。 Docker的镜像存储在/var/lib/docker目录下,存储方式有点像Git那样有reference和实际的objects,并且是实际内容是diff那样的增量存放。 Docker的镜像存储在哪里 有个疑问就是我们用docker pull镜像后,该镜像是存储在哪里的? 当你仅仅是使用docker启动一个实例的时候,是超级简单的,但是当你制作自己的Dockerfile时,可能会有一些迷惑,那就是我的docker镜像存储在哪里了。这个听起来让我感觉有点一筹莫展,对于dockerimage的存储我还是一无所知。最后你只能把镜像发布到公共DockerIndex上面,但是,在过去一段时间内你是无法删除它的,但是现在你可以通过官方的WEB界面来删除它了。 Image VS Dockerfile 这个看起来有点混淆,但是它们是有差别的,docke使用images运行你的代码,而不是Dockerfile。Dockerfile是你用dockerbuild命令来构建image的。如果你在浏览器中浏览DockerIndex,你会发现有很多images显示在上面,但是你不能看见构建它们的Dockerfile。当你使用dockerpush命令发布image时,它不会发布你的源代码,它只会发布从你源代码构建出来的镜像。 Registry VS Index 下一个混淆的是Registry和Index,它们是怎么样区分的?index是管理公共web接口上的accounts、permission、search、tagging和所有精细的方面的。而registry是存储和提供实际image的,它委托index进行身份验证。当你运行dockersearch命令的时候,它搜索的是index,而不是registry。实际上,它可能搜索的是index知道的多个registry。当你运行dockerpush或者dockerpull命令时,index决定你是否有权限访问和修改images,当index同意你操作后,registry是提供images存储的地方,index会计算出哪个registry有你需要的镜像,并把请求转发过去。当你在本地运行dockerimages命令时,你可能是同时和index和registry进行交互。 Repository docker’s使用镜像就像使用GitHub一样容易,但是有三个混淆的地方: repository和registry之间的区别 repository和image之间的区别 repository和index username之间的区别 其实repository并不是其中任何一个组件,而是指所有的组件。当你运行dockerimages命令时,你会看到如下: images列表看起来像repositories列表?实际上images是GUIDs,但这并不是如何和他们交互。当你执行dockerbuild或者dockercommit命令时,你可以指定image的名称,这个名称的格式是username/image_name,但这并不一定,它可以是任何形式的,他甚至可以是你已经知道的发布的镜像名称。当你执行dockerpush的时候,index会查看镜像名称,检查该镜像是否在repository中,如果在,接着检查你是否有权限访问该repository,如果有权限,则允许你push新版本的image到该repository上。因此,一个registry保留了它收集到的repository的名称,它本身跟踪收集到的images的GUIDs。thisis also where tags comein,你可以tag一个image,并且存储多个版本使用不同的GUIDs在同一个repository中,访问不同的标记的版本image,可以使用username/image_name:tag。 从上图中你可以看到我们有三个不同版本的image叫ubuntu12,每个的tag都是不同的,repository使用ubuntu12的名称来保存这些,因此,当我们看到ubuntu12的时候,它像一个image名称,但是实际上它使repository名称,repository名称有特殊的设计架构,index可以从第一部分解析出username,并且找出他在哪里。因此,当出现一个guol/ubuntu时会产生混淆,官方的repository名称是类似username/image_name这样的,我们想当然的认为repository名称是image_name,但是根据docker的文档发现repository的名称有时指的是全部的名称,有时指的是image_name。比如就像ubuntu,它就没有username,是不是有点乱了……… Local Storage on the Docker Host 我们已经了解完如何和远程存储进行交互了,但是当你运行dockerimages的时候,仅仅给你看到的是你的机器上有哪些image。这些镜像在哪里呢?第一个要查看的地方是/var/lib/docker/。 查看repositories-aufs文件的内容,它的内容是在你本机上的repositories。 看看,它完全匹配了docker images的输出内容。 现在我们来看看/var/lib/docker/graph/的内容。 我倒,显示的非常不友好啊,看看docker是怎样跟踪这些镜像的,是基于repositories-aufs文件,构建了一个映射到repository名称和tag的关系表。我们看看ubuntu12的仓库,它有三个镜像,标记分别是12.04、precise、latest。采用的是IDd431f556799d35dfae1278a1ee41a393db70058dedb9a7fc554b0506b5b241cb,我们看看这个目录里面有什么。 只有两个文件: json:保存image的metadata layersize:只是一个数字,表明layer的大小 主要镜像的差异在/var/lib/docker/aufs/diff/目录下,每次都会把镜像改变的部分存储在该目录下的相关ID目录里面。 参考:Where are Docker images stored?

断路器(CircuitBreaker)设计模式

时间: 2015-07-04   |   分类: Tech     |   阅读: 41 字 ~1分钟
断路器是电器时代的一个重要组成部分,后面总是有保险丝熔断或跳闸的断路器是安全的重要保障。 微服务最近几年成为软件架构的热门话题,其益处多多。但需要知道的是,一旦开始将单块系统进行分解,就上了分布式系统的山头。 在云或分布式系统环境中,任何对一致性或可靠性的表述就是谎言。我们必须假设微服务的行为或其服务器位置会经常变动,其结果就是组件有时会提供低质量服务甚至可能彻底无法提供服务。这些微服务的故障如果没有处理好,将导致整个系统的故障。 微服务的故障可能是瞬时故障:如慢的网络连接、超时,资源过度使用而暂时不可用;也可能是不容易预见的突发事件的情况下需要更长时间来纠正的故障。 分布式服务的容错是一个不得不考虑的问题,通常的做法有两种: 重试机制:对于预期的短暂故障问题,通过重试模式是可以解决的。 断路器(CircuitBreaker)模式:将受保护的服务封装在一个可以监控故障的断路器对象中,当故障达到一定门限,断路器将跳闸(trip),所有后继调用将不会发往受保护的服务而由断路器对象之间返回错误。对于需要更长时间解决的故障问题,不断重试就没有太大意义了,可以使用断路器模式。 断路器模式设计状态机 注意事项 在决定如何实现这个模式时,您应考虑以下几点: **异常处理。**通过断路器调用操作的应用程序必须能够处理在操作不可用时可能被抛出的异常,该类异常的处理方式都是应用程序特有的。例如,应用程序会暂时降级其功能,调用备选操作尝试相同的任务或获取相同的数据,或者将异常通知给用户让其稍后重试。 **异常类型。**一个请求可能由于各种原因失败,其中有一些可能表明故障严重类型高于其他故障。例如,一个请求可能由于需要几分钟才能恢复的远程服务崩溃而失败,也可能由于服务暂时超载造成的超时而失败。断路器有可能可以检查发生的异常类型,并根据这些异常本质调整策略。例如,促使切换到开状态(跳闸)的服务超时异常个数要远多于服务完全不可用导致的故障个数。 **日志记录。**一个断路器应记录所有失败的请求(如果可能的话记录所有请求),以使管理员能够监视它封装下受保护操作的运行状态。 **可恢复性。**应该配置断路器成与受保护操作最匹配的恢复模式。例如,如果断路器设定出入开状态的时间很长,即使底层操作故障已经解决它还会返回错误。如果开状态到半开状态切换过快,底层操作故障还没解决它就会再次调用受保护操作。 **测试失败的操作。**在开状态下,断路器可能不用计时器来确定何时切换到半开状态,而是通过周期性地查验远程服务或资源以确定它是否已经再次可用。这个检查可能采用上次失败的操作的形式,也可以使用由远程服务提供的专门用于测试服务健康状况的特殊操作。 **手动复位。**在一个系统中,如果一个失败的操作的恢复时间差异很大,提供一个手动复位选项以使管理员能够强行关闭断路器(和复位故障计数器)可能是有益的。同样,如果受保护操作暂时不可用,管理员可以强制断路器进入放状态(并重新启动超时定时器)。 **并发。**同一断路器可以被应用程序的大量并发实例访问。断路器实现不应阻塞并发请求或对每一请求增加额外开销。 **资源分化。**当断路器使用某类可能有多个底层独立数据提供者的资源时需要特别小心。例如,一个数据存储包含多个分区(shard),部分分区出现暂时的问题,其他分区可能完全工作正常。如果该场景中的错误响应是合并响应,应用程序在部分故障分区很可能会阻塞整个请求时仍会试图访问某些工作正常的分区。 **加速断路。**有时失败响应对于断路器实现来说包含足够的信息用于判定应当立即跳闸并保持最小时间量的跳闸状态。例如,从过载共享资源的错误响应可能指示不推荐立即重试,且应用程序应当隔几分钟时间之后重试。如果一个请求的服务对于特定Web服务器不可用,可以返回HTTP协议定义的“HTTP 503 ServiceUnavailable”响应。该响应可以包含额外的信息,例如预期延迟持续时间。 **重试失败请求。**在开状态下,断路器可以不是快速地简单返回失败,而是将每个请求的详细信息记录日志并在远程资源或服务重新可用时安排重试。 **对外部服务的不恰当超时。**当对外部服务配置的超时很大时,断路器可能无法保护其故障操作,断路器内的线程在指示操作失败之前仍将阻塞到外部服务上,同时很多其他应用实例仍会视图通过断路器调用服务。 断路器模式业界Java实现 GitHub:jrugged:CircuitBreaker类源代码 GitHub:Netflix/hystrix 参考 Martin Fowler:CircuitBreaker MSDN:Circuit Breaker Pattern Protect your software with the Circuit Breaker design pattern

聊聊mavenCenter和JCenter

时间: 2015-07-03   |   分类: Tool     |   阅读: 5 字 ~1分钟
Gradle支持从maven中央仓库和JCenter上获取构件,那这两者有什么区别呢? maven中央仓库(http://repo1.maven.org/maven2/)是由Sonatype公司提供的服务,它是ApacheMaven、SBT和其他构建系统的默认仓库,并能很容易被ApacheAnt/Ivy、Gradle和其他工具所使用。开源组织例如Apache软件基金会、Eclipse基金会、JBoss和很多个人开源项目都将构件发布到中央仓库。maven中央仓库已经将内容浏览功能禁掉了,可在http://search.maven.org/查询构件。 https://jcenter.bintray.com)是由JFrog公司提供的Bintray中的Java仓库。它是当前世界上最大的Java和Android开源软件构件仓库。所有内容都通过内容分发网络(CDN)使用加密https连接获取。JCenter是Goovy Grape内的默认仓库,Gradle内建支持(jcenter()仓库),非常易于在(可能除了Maven之外的)其他构建工具内进行配置。 JCenter相比mavenCenter构件更多,性能也更好。但还是有些构件仅存在mavenCenter中。
23 24 25 26 27 28 29 30 31

Programmer & Architect

662 日志
27 分类
1472 标签
RSS 订阅
GitHub Twitter FB Page
© 2009 - 2023 Mryqu's Notes
Powered by - Hugo v0.120.4
Theme by - NexT
0%