0%

最近遇到一个需求需要在获取URL字符串上的kv键值对,我们都知道Java Web在请求是直接用request来获取值的。如果是字符串呢,就需要正则表达式来自己截取了。
自己写代码是比较麻烦的,下面推荐用Guava工具包,2行代码就可以解决这个需求了。

1
2
3
4
5
6
private String getPara(String url, String name) {
String params = url.substring(url.indexOf("?") + 1, url.length());
Map<String, String> split = Splitter.on("&").withKeyValueSeparator("=").split(params);
return split.get(name);
}

先截取到?后面的字符串,然后再用Splitter.on("&").withKeyValueSeparator("=").split(params);就轻松的解决了~

Spring Cloud oauth2 开启客户端功能,并启用LoadBalanced

如果不添加以下配置,只添加@EnableOAuth2Client注解,spring cloud默认是在web环境下使用的AuthorizationCodeResourceDetails

具体代码在OAuth2RestOperationsConfiguration类中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

@Configuration
@ConditionalOnBean(OAuth2ClientConfiguration.class)
@ConditionalOnWebApplication
protected static class SessionScopedConfiguration {

@Bean
@ConfigurationProperties("security.oauth2.client")
@Primary
public AuthorizationCodeResourceDetails oauth2RemoteResource() {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
return details;
}

@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(
OAuth2ClientContextFilter filter, SecurityProperties security) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(security.getFilterOrder() - 10);
return registration;
}

@Configuration
protected static class ClientContextConfiguration {

@Resource
@Qualifier("accessTokenRequest")
protected AccessTokenRequest accessTokenRequest;

@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public DefaultOAuth2ClientContext oauth2ClientContext() {
return new DefaultOAuth2ClientContext(this.accessTokenRequest);
}

}

}

阅读全文 »

在项目中访问另一个微服务的时候我们可以这样用RestTemplate来调用其他服务:

1
2
3
4
@Autowired
private RestTemplate restTemplate;
RestResponse response = restTemplate.postForObject("http://user-service/user/getUser", para, User.class);

在spring cloud环境下,这个注入的restTemplate是具备了客户端负载均衡功能的,也会用到eureka服务发现功能,user-service就是服务的名称。
我的项目启用了oauth2认证。spring cloud也提供了一个OAuth2RestTemplate来很方便的调用其他服务。但是在我测试的时候一直报错UnknownHost,我猜测他肯定是没有用到loadBalanced和eureka的服务发现功能。我翻遍了官方文档也没有找到相关的说明。

Google搜了大半天后,看了作者在git也讨论过这个类loadBalanced功能之类的,还翻到一个没有什么用 @LoadBalanced注解,翻了半天源码后终于在OAuth2LoadBalancerClientAutoConfiguration这样一个类中发现了一点蛛丝马迹。

阅读全文 »

在spring cloud项目环境中配置oauth2.0认证。

http://callistaenterprise.se/blogg/teknik/2015/04/27/building-microservices-part-3-secure-APIs-with-OAuth/
可以先看看这篇文章。

我花了不少时间才把这个调通,spring cloud的版本和文档也存在不一致的地方。
以下所有的操作都基于Brixton.RC1搭建,须保持所有相关项目都引用此parent。否则会出现各种莫名其妙的错误。

1
2
3
4
5
6
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.RC1</version>
<relativePath/>
</parent>
阅读全文 »

配置中心和服务注册中心

我们先把配置中心和服务注册中心跑起来,这个先照着之前的教程做,很简单没什么变动。
就是git仓库需要密码的话加入下面的配置就好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server:
port: 8888

eureka:
instance:
hostname: configserver
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://${config.host:192.168.99.100}:8761/eureka/

spring:
cloud:
config:
server:
git:
uri: yourgiturl
password: ****
username: ****

这里的${config.host:192.168.99.100}表示没有读到config.host就用192.168.99.100这个值。

1
java -jar cloud-simple-service-1.0.0.jar --config.host=localhost

这个用法就很灵活了,后面配合Dockerfile可以根据不同的环境来启动不同的配置。

阅读全文 »

基本概念和重要组件

最近看了一篇文章,了解到微服务架构的组成部分和概念,以前有看过一点dubbo,文章里介绍到Netflix这么一个公司:

Netflix是一家成功实践微服务架构的互联网公司,几年前,Netflix就把它的几乎整个微服务框架栈开源贡献给了社区,这些框架和组件包括

  • Eureka: 服务注册发现框架
  • Zuul: 服务网关
  • Karyon: 服务端框架
  • Ribbon: 客户端框架
  • Hystrix: 服务容错组件
  • Archaius: 服务配置组件
  • Servo: Metrics组件
  • Blitz4j: 日志组件

Netflix的开源框架组件已经在Netflix的大规模分布式微服务环境中经过多年的生产实战验证,正逐步被社区接受为构造微服务框架的标准组件。Pivotal去年推出的Spring Cloud开源产品,主要是基于对Netflix开源组件的进一步封装,方便Spring开发人员构建微服务基础框架。对于一些打算构建微服务框架体系的公司来说,充分利用或参考借鉴Netflix的开源微服务组件(或Spring Cloud),在此基础上进行必要的企业定制,无疑是通向微服务架构的捷径。

Spring Cloud是微服务工具包,为开发者提供了在分布式系统的配置管理、服务发现、断路器、智能路由、微代理、控制总线等开发工具包。

觉得挺不错的,就找找资料尝试实战一下。
在此记录和回顾一下过程中遇到的问题和实际项目中需要解决的一些问题。

阅读全文 »

今天来说一下如何用jenkins做持续集成。
jenkins我这里就不介绍了,重点介绍一下如何用jenkins对tomcat进行持续集成。

思路

流程是这样的:

  1. jenkins从git(or svn)拉取代码,进行构建。
  2. 将打出来的war包用jenkins的插件(Publish over SSH)传到你要部署的服务器。
  3. 执行一个shell脚本,将正在运行的tomcat进程kill掉,把war包拷到tomcat目录的webapps下。然后在运行${TOMCAT_DIR}/bin/startup.sh。
    阅读全文 »

枚举

我们在写程序的时候会遇到这种需求。就是我的对象里面有一个属性是一个枚举值,但是mybatis默认是不支持的,官方提供了一个typeHandler可以用枚举的ordinal()来进行存和取的自动转换。把它配置在
mybatis-configuration.xml里。

1
2
3
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.xxx.user.UserType"/>
</typeHandlers>
阅读全文 »