Spring Boot 集成 HBase的一些注意事项
Spring boot 确实降低了开发一个符合现代架构Java Web应用的门槛,不过由于普及范围不太广,资历也还比较年轻,相关文档和Spring MVC那套比起来相当贫乏。
所以可能会趟到一些坑。
实话讲,Spring boot开发一个Java Web应用是十分称职的,不论是做Restful API提供纯后台服务,还是使用MVC加上一些模板渲染引擎,Spring boot都可以胜任,并能简单的、出色的完成工作。与Spring进行一大堆配置相比,Spring boot的配置非常简单。数据连接方面,Spring boot data组件涵盖了大多数应用场景,jpa写到飞起,默认的tomcat连接池也可满足一般需求。
我最近一个需求是进行HBase数据检索。
spring-data-hadoop的hbaseTemplate挺强大的,我初步想集成进来,不过这个组件现在Spring boot里没有办法做到简单配置,还需要写xml的配置文件并显式生效。官方现在尚无简单进行hbase集成的文档和参考案例,相关的讨论可以看这两个帖子:
http://stackoverflow.com/questions/31381615/use-hbase-with-spring-boot
http://stackoverflow.com/questions/24795097/how-to-use-hbase-with-spring-boot-using-java-instead-of-xml
不过hbase原生api使用起来也不麻烦,我要开发的这个应用十分简单,心想索性就引入原生的包直接写就好了。
所以我引入了hbase-client和hadoop-hdfs两个包,就像这样
org.apache.hbase
hbase-client
1.2.0
org.slf4j
slf4j-log4j12
org.mortbay.jetty
servlet-api-2.5
org.mortbay.jetty
servlet-api-2.5-6.1.14
org.apache.hadoop
hadoop-hdfs
2.6.0
servlet-api
javax.servlet
可惜跪了
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/.m2/repository/ch/qos/logback/logback-classic/1.1.5/logback-classic-1.1.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
这个好解决啦,把slf4j-log4j12排除就好了,像这样
org.apache.hbase
hbase-client
1.2.0
org.slf4j
slf4j-log4j12
但是又悲剧了
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
这个比较隐晦,原来是内嵌的tomcat的servlet和hadoop-hdfs包里的冲突了,也是排除掉就好了。
org.apache.hadoop
hadoop-hdfs
2.6.0
servlet-api
javax.servlet
就可以happy的运行了。
但Native的API没有被Spring接管,所以每次需要加载配置等操作,如果硬编码也很蛋疼,可以使用自动装配的构造函数,结合用户自定义配置文件来做,就非常省心了,例如:
@Autowired
public SearchDaoImpl(AppSettings appSettings){
this.appSettings = appSettings;
Configuration HBASE_CONFIG = new Configuration();
//与hbase/conf/hbase-site.xml中hbase.zookeeper.quorum配置的值相同
HBASE_CONFIG.set("hbase.zookeeper.quorum", appSettings.getHbasename());
//与hbase/conf/hbase-site.xml中hbase.zookeeper.property.clientPort配置的值相同
HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", appSettings.getHbaseport());
conf = HBaseConfiguration.create(HBASE_CONFIG);
}
谢谢大佬!