如何在predix上构建使用postgresql服务的Java Webapp
来源:互联网 发布:深圳软件开发工资水平 编辑:程序博客网 时间:2024/05/22 06:23
如何在predix上构建使用postgresql服务的Java Webapp
目的
演示如何在predix上使用postgres服务
webapp 特性
- 在本地使用h2数据库作为数据源
- 在predix云端使用postgres服务作为数据源
- 云端部署的时候禁止spring auto-reconfiguration, 隐藏我们可以使用自定义的数据库连接池
- 使用druid jdbc连接池来monitor数据库使用
- 在本地时使用h2的web console来查询和处理数据
项目源文件
https://github.com/iintothewind/PsqlSimple
一些需要注意的地方
数据库初始化脚本
我们可以在src/main/resources/h2/下面创建初始化数据库的sql文件,等webapp启动的时候可以通过spring的脚本初始化帮我们初始化数据库。
spring配置里面通过调用初始化数据库的配置在src/main/resources/spring/mvc.xml文件中:
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS"> <jdbc:script location="classpath:h2/init.sql"/> </jdbc:initialize-database>
另外不要忘了在xml头部引入jdbc的xmlns和xsi:schemaLocation
H2数据库的web console配置
首先需要确保在pom文件中引入h2, 需要确保h2的scope为runtime:
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.192</version> <scope>runtime</scope> </dependency>
然后在src/main/webapp/WEB-INF/web.xml中加入:
<servlet> <servlet-name>H2Console</servlet-name> <servlet-class>org.h2.server.web.WebServlet</servlet-class> <init-param> <param-name>webAllowOthers</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>H2Console</servlet-name> <url-pattern>/h2/*</url-pattern> </servlet-mapping>
数据库连接
predix的jdbc连接配置如果引入的spring就会很容易出问题,因为默认的Java Buildpack会检测spring的jdbc datasource配置,然后自动替换掉, 这样的话我们的一些连接池优化就没办法做了,如果需要我们自己配置jdbc连接就必须要禁掉Java Buildpack的auto-reconfiguration, 如下在manifest.xml中
application子项下面加入JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'
:
applications:- name: psqlsimple env: JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '{enabled: false}'
这样的话Java Buildpack就不会自动替换我们的jdbc连接配置了。
接下来我们需要写一个类来帮我获取jdbc连接所需要的参数, 因为如果我们在创建app的时候绑定了jdbc服务,那么host,port,database, username,password, jdbc_uri等参数等参数将会出现在这个app的system env中,
我们通过调用System.getenv("VCAP_SERVICES")
就可以获取到这些参数,predix.psql.config.CloudCfg是用来自动获取本地jdbc配置或者云端system env中postgres参数的类,源代码如下:
package predix.psql.config;import com.typesafe.config.Config;import com.typesafe.config.ConfigFactory;import com.typesafe.config.ConfigValueFactory;import javaslang.control.Try;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class CloudCfg { private final static Logger log = LoggerFactory.getLogger(CloudCfg.class); private final String jdbcHost; private final int jdbcPort; private final String jdbcDatabase; private final String jdbcUserName; private final String jdbcPassword; private final String jdbcUrl; public CloudCfg() { Config cfg = Try.of(() -> (Config) ConfigFactory.parseString(System.getenv("VCAP_SERVICES")).getConfigList("postgres").get(0)) .getOrElse(ConfigFactory.parseResources(this.getClass().getClassLoader(), "database.properties").withFallback(ConfigFactory.empty() .withValue("credentials.host", ConfigValueFactory.fromAnyRef("localhost")) .withValue("credentials.port", ConfigValueFactory.fromAnyRef(5432)) .withValue("credentials.database", ConfigValueFactory.fromAnyRef("test")) .withValue("credentials.username", ConfigValueFactory.fromAnyRef("postgres")) .withValue("credentials.password", ConfigValueFactory.fromAnyRef("root")) .withValue("credentials.jdbc_uri", ConfigValueFactory.fromAnyRef("jdbc:h2:mem:test;MVCC=TRUE;DB_CLOSE_DELAY=-1;MODE=POSTGRESQL")))); jdbcHost = cfg.getString("credentials.host"); jdbcPort = cfg.getInt("credentials.port"); jdbcDatabase = cfg.getString("credentials.database"); jdbcUserName = cfg.getString("credentials.username"); jdbcPassword = cfg.getString("credentials.password"); jdbcUrl = cfg.getString("credentials.jdbc_uri"); } public String getJdbcHost() { return jdbcHost; } public int getJdbcPort() { return jdbcPort; } public String getJdbcDatabase() { return jdbcDatabase; } public String getJdbcUserName() { return jdbcUserName; } public String getJdbcPassword() { return jdbcPassword; } public String getJdbcUrl() { return jdbcUrl; }}
CloudCfg
这个类将会首先尝试读取system env的VCAP_SERVICES
变量,并解析postgres参数配置, 如果获取失败,则尝试读取系统根目录的database.properties
文件获取配置,如果再次失败,则尝试使用代码中给定
的fallback配置。
druid数据库连接池的配置和监控设置
首先在spring中使用druid 数据库连接池作为数据源
在src/main/resources/spring/mvc.xml中加入
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="#{cloudCfg.jdbcUrl}"/> <property name="username" value="#{cloudCfg.jdbcUserName}"/> <property name="password" value="#{cloudCfg.jdbcPassword}"/> <property name="initialSize" value="1"/> <property name="minIdle" value="1"/> <property name="maxActive" value="50"/> <!--<property name="maxWait" value="60000"/>--> <property name="timeBetweenEvictionRunsMillis" value="60000"/> <property name="minEvictableIdleTimeMillis" value="300000"/> <property name="validationQuery" value="SELECT 'x'"/> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <property name="removeAbandoned" value="true"/> <property name="removeAbandonedTimeout" value="10"/> <property name="logAbandoned" value="true"/> <property name="poolPreparedStatements" value="true"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="5000"/> <property name="proxyFilters"> <list> <ref bean="statFilter"/> <ref bean="wallFilter"/> <ref bean="slf4jLogFilter"/> </list> </property> </bean> <bean id="cloudCfg" class="predix.psql.config.CloudCfg"/> <bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter"> <property name="logSlowSql" value="true"/> <property name="slowSqlMillis" value="5000"/> <property name="mergeSql" value="true"/> </bean> <bean id="wallFilter" class="com.alibaba.druid.wall.WallFilter"> <property name="dbType" value="postgresql"/> <property name="logViolation" value="true"/> <property name="throwException" value="false"/> </bean> <bean id="slf4jLogFilter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter"> <property name="statementExecutableSqlLogEnable" value="true"/> <property name="connectionLogErrorEnabled" value="true"/> <property name="statementLogErrorEnabled" value="true"/> <property name="resultSetLogErrorEnabled" value="true"/> </bean>
- DruidDataSource的url,username,password属性需要从cloudCfg这个bean中获取。
- statFilter用来支持web端的页面监控
- wallFilter提供sql入侵检测支持
- slf4jLogFilter提供sql执行日志支持
在src/main/webapp/WEB-INF/web.xml中加入:
<servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> <init-param> <param-name>resetEnable</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>loginUsername</param-name> <param-value>druid</param-value> </init-param> <init-param> <param-name>loginPassword</param-name> <param-value>druid</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping> <filter> <filter-name>druidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value> *resource/*,*resources/*,/druid*,/public/*,*.js.xhtml,*.css.xhtml,*.png.xhtml,*.jpg.xhtml,*.svg.xhtml,*.swf </param-value> </init-param> <init-param> <param-name>principalSessionName</param-name> <param-value>sessionInfo</param-value> </init-param> <init-param> <param-name>profileEnable</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>druidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>
运行
请参考https://github.com/iintothewind/PsqlSimple 的readme来部署和运行app
- 如何在predix上构建使用postgresql服务的Java Webapp
- 在Predix上创建PostgreSQL数据服务
- 在Predix上创建邮件通知服务
- 使用Predix的邮件通知服务
- 在Predix上运行Scala的HelloWorld
- 如何在Predix上建立一个简单的Node.js 程序
- benchmarksql在postgresql上的安装、使用
- 在CentOS 7上使用PaceMaker构建NFS HA服务
- 在webapp上使用input:file
- 如何在Predix上进行不停机部署Apps(蓝绿部署)
- PostgreSQL在RHEL5上的安装和简单使用
- 如何在openSUSE上安装postgresql数据库
- 使用Oauth构建webapp应用
- 如何在linux(ubuntu)上使用java的jni
- 服务程序编写-------详细介绍如何构建你自己的服务程序(上)
- 甘泉-如何在云上构建复杂的企业应用
- Log4j在Java WebApp的配置
- 在Heroku平台上部署maven webapp(java web)项目
- Swift-使用 R.swift 优雅的使用资源文件
- java数组元素倒序的三种方法
- Nginx + uwsgi + Django 简单上线配置
- weblogic项目可以没有web.xml文件?
- js学习笔记
- 如何在predix上构建使用postgresql服务的Java Webapp
- FTP连接图片上传工具类
- python 位运算
- tomcat部署项目方式
- 如何解决电脑无法访问个别网站
- Opencv显示图片的窗口大小
- Android 使用原始xml资源
- 线性筛法求素数
- 一次性加载数据,前端分页