JavaEE解决方案配置最佳实践
我们构建 3 层企业解决方案,通常由多个 webapp 和 ejbjar 模块组成,这些模块都与数据库通信并具有多个外部集成点。
每个模块通常需要自己的配置,这些配置可以在解决方案的生命周期内发生变化。 部署它变成了一场噩梦,因为现在我们有 18 个属性文件,必须记住复制和配置这些文件,还设置数据源、队列、内存要求等。
我对有更好的方法充满希望但并不乐观。 我们考虑/使用了一些选项,每个选项都有其优点和缺点:
- 使用多个 Maven 项目和持续集成(例如 hudson 或 jenkins)来构建一个配置 jar,其中包含每个环境的所有属性文件(dev、qa、prod) )然后将所有内容打包为 EAR。但当需要时,在生产中就无法轻易改变事情了。
- 将大部分设置放在数据库中,并有一个简单的屏幕来修改它。在内部,我们可以拥有一个可以读取和修改值的通用配置服务 EJB。每个模块都可以有一个自定义扩展版本,该版本具有特定的 getter 和 setter。
- 对所有属性文件进行版本控制,然后在生产中将其检出,并在进行更改后将其检入生产分支。
有了所有这些,您仍然需要以容器特定的方式配置数据源和队列等:(
We build 3-tier enterprise solutions that typically consists of several webapp and ejbjar modules that all talk to a db and have several external integration points.
Each module typically needs its own configurations that can change over the solution's life time.
Deploying it becomes a nightmare because now we have 18 property files that must be remembered to copied over and configured also setting up data-sources, queues, memory requirements etc.
I'm hopeful but not optimistic that there can be a better way.
Some options we've considered/used, each with it's pros and cons:
- Use multiple maven projects and continuous integration (eg. hudson or jenkins) to build a configuration jar that includes all the property files for each environment (dev, qa, prod) and then bundle everything up as an EAR. But then things can't be easily changed in production when needed.
- Put most of the settings in the DB and have a simple screen to modify it. Internally we can have a generic configuration service EJB that can read and modify the values. Each module can have a custom extended version that have specific getters and setter.
- Version control all the property files then check it out on production and check it into a production branch after making changes.
With all of these you still need to configure data-sources and queues etc. in a container specific way :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Map
或Properties
。MBean Server
,然后使用jconsole
或visualvm
等知名工具进行配置您的应用程序的组件。两种方式都支持在运行时动态重新配置应用程序。我更喜欢使用
JMX
。JNDI
. Then lookup this object in your apps to configure them. Benefits - you can use custom configuration object instead of rather genericMap
orProperties
.JMX
to configure applications you need. Benefits - you can bind objects you have to configure directly toMBean Server
and then use such a well-known tools asjconsole
orvisualvm
to configure components of your application.Both ways support dynamic reconfiguration of your applications at runtime. I would prefer using
JMX
.我已经经历了几个寻找方法来做到这一点的循环。我仍然没有确定的答案。
上一个周期以基于属性文件的过程结束。这个想法是每个服务器实例都配置有一个配置所有内容的属性文件。该文件由启动脚本读取,以设置内存参数、由应用程序服务器和应用程序本身读取。
但关键是该文件不是直接管理的。相反,它是构建过程的产物。我们有一系列用于不同目的的文件,保存在版本控制中,以及合并适当文件的构建步骤。这可以让您找出沿各个轴共享的共性。
例如,我们有开发、持续集成、QA、UAT、登台和生产环境,每个环境都有自己的数据库。不同环境中的服务器需要不同的数据库设置,但给定环境中的每台服务器都使用相同的设置。因此,就有了诸如development-db.properties、qa-db.properties 之类的东西。在每个环境中,我们都有多种服务器 - Web 服务器、内容管理服务器、批处理服务器等。每种服务器都有 JVM 设置、堆大小等,这些设置与其他类型的服务器不同,但跨服务器之间保持一致环境。因此,我们有 web-jvm.properties、cms-jvm.properties、batch-jvm.properties 等内容。我们还有一种方法可以覆盖特定系统 - production-cms-jvm.properties 之类的东西。我们还有一个 common.properties 来设置公共属性,以及可以在需要时覆盖的合理默认值。
我们的构建过程实际上比仅仅从每组中选择正确的选项要复杂一些;我们为每个环境中的每个服务器都有一个主文件,其中指定了要包含哪些其他文件。我们允许文件指定要包含的其他文件,因此我们可以构建导入图以最大限度地重用。
结果变得相当复杂。我认为太复杂了。但它确实有效,并且确实使得以受控方式进行影响许多服务器的更改变得非常非常容易。我们甚至合并了一组来自开发的输入文件和一组来自运营的输入文件,其中包含敏感信息。这是一种非常灵活的方法。
I've gone through several cycles of finding ways to do this. I still don't have a definite answer.
The last cycle ended up with a process based on properties files. The idea was that each server instance was configured with a single properties file that configured everything. That file was read by the startup scripts, to set memory parameters, by the app server, and by the application itself.
The key thing, though, was that this file was not managed directly. Rather, it was a product of the build process. We had a range of files for different purposes, kept in version control, and a build step which merged the appropriate ones. This lets you factor out commonalities that are shared along various axes.
For example, we had development, continuous integration, QA, UAT, staging, and production environments, each with its own database. Servers in different environments needed different database settings, but each server in a given environment used the same settings. So, there was something like a development-db.properties, qa-db.properties, and so on. In each environment, we had several kinds of servers - web servers, content management servers, batch process servers, etc. Each had JVM settings, for heap size and so on, that were different to other kinds of servers, but consistent between servers across environments. So, we had something like web-jvm.properties, cms-jvm.properties, batch-jvm.properties, and so on. We also had a way to have overrides for specific systems - production-cms-jvm.properties sort of thing. We also had a common.properties that set common properties, and sensible defaults which could be overridden where needed.
Our build process was actually a bit more complicated than just picking the right options from each set; we had a master file for each server in each environment which specified which other files to include. We allowed files to specify other files to include, so we could build a graph of imports to maximise reuse.
It ended up being quite complicated. Too complicated, i think. But it did work, and it did make it very, very easy to make changes affecting many servers in a controlled way. We even merged a set of input files from development, and another from operations, which contained sensitive information. It was a very flexible approach.
我知道这个问题已经得到了回答,我的答案不一定是通用的,但这是我的看法:
注意,这里我只考虑系统/资源属性,而不是应用程序设置。在我看来,应用程序设置(例如支付阈值或其他设置应存储在数据库中,以便可以重新配置系统,而无需重新启动服务或通过重新部署或重新读取属性文件而导致停机) 。
对于影响系统不同部分如何相互连接的设置(例如 Web 服务端点等),我将使用 JNDI 树。
然后,数据库连接和 JMS 连接将使用 Websphere 控制台进行设置,并可由 Websphere 管理员进行管理。这些也可以创建为 JACL 脚本,如有必要,可以将其放入版本控制中。
除了 JNDI 资源之外,对于其他属性,例如对后端的 Web 服务调用的用户名等,我将使用 Websphere“名称空间绑定”。这些绑定可以使用 Websphere 控制台进行编辑,并使用“cell/persistent/mypassword”名称通过 JNDI 进行访问。
因此,我可以创建“mypassword”绑定(一个字符串),并且它的管理权由 Websphere 管理员负责(远离开发人员或其他不应访问生产系统的人),同时可以使用相同的 EAR 文件开发、测试、预生产和生产(最好为不同的系统使用不同的 EAR 文件,因为其他差异渗透的可能性会降低)。
然后,Java 代码将使用简单的 JNDI 查找(并可能将值缓存在内存中)。
相对于属性文件的优点:
相对于数据库属性的优点:
希望有帮助
I know this has already been answered and my answer is not necessarily generic, but here's my take on things:
Note, here I'm only considering system/resource properties, not application settings. In my view, application settings (such as a payment threshold or other settings should be stored in a database, so that the system can be reconfigured without having to restart a service or cause downtime by re-deploying or re-reading a properties file).
For settings that impact on how different parts of a system connect with each other (such as web service endpoints, etc), I would make use of the JNDI tree.
Database connectivity and JMS connectivity would then be set-up using the Websphere console and can be managed by the Websphere administrators. These can also be created as JACL scripts which can be put into version control if necessary.
In addition to the JNDI resources, for additional properties, such as usernames for web service calls to a backend, etc, I would use Websphere "Name Space Bindings". These bindings can be edited using the Websphere console and accessed via JNDI using the "cell/persistent/mypassword" name.
So I could create the "mypassword" binding (a string), and the management for it falls to the Websphere admin (away from developer eyes or other people who should not have access to production systems), while the same EAR file can be used on dev, test, preproduction and production (which is preferable to have different EAR files for different systems, as the likelihood of other differences creeping in is reduced).
The Java code would then use a simple JNDI lookup (and possibly cache the value in memory).
Advantages over properties files:
Advantages over database properties:
Hope that helps
我认为配置应该位于应用程序实例的数据库中。您的本地计算机配置可能与开发、QA、PROD、DR 等不同。
您需要的是一种以简单的方式从数据库中获取配置的方法。
我创建了一个单独的项目,并提供了 Apache commons-configuration 的依赖项
它有很多存储数据的方式,但我喜欢数据库,并且配置存在于数据库环境中。
Commons 配置作为一个简单的 API,然后您可以根据需要编写 GUI。
您可以按照您希望的任何方式制作界面。或者作为快速获胜没有界面。
版本控制很棒。使用组合添加另一个 DatabaseConfiguration。您扩展的类是活动配置,而组合类是审核。还有另一个构造函数可以有一个版本。只需重载正确的方法即可获得所需的效果。
http://commons.apache.org/proper/commons-configuration/
I think the config should be in the database of the application instance. Your local machine config may be diffrent to dev and to QA, PROD , DR etc.
What you need is a way of getting the config out the database in a simple way.
I create a separate project with a provided dependency of Apache commons-configuration
It has many ways of storing data, but I like databases and the configurations lives in the database environment.
Commons configurations as a simple API, you may then write the GUI as you wish.
You can do the interface in anyway you wish. Or as a quick win have no interface.
Version control is great. Add another DatabaseConfiguration using composition. The class you extends is the active config and the composed one being the audit. There is another constructor can can have a version. Just overload the right methods to get the desired effect.
http://commons.apache.org/proper/commons-configuration/
用户一个简单的数据库表(部分、键、值)。如果需要,添加“Version”,然后使用 getInt(String section, String key) 等方法将整个内容包装在一个简单的 ConfigurationService 类中。
工作量不大,而且它使应用程序代码非常简单。整洁,并且很容易调整配置。
User a simple database table (Section, Key, Value). Add "Version" if you need it, and wrap the entire thing in a simple ConfigurationService class with methods like
getInt(String section, String key)
Not a lot of work, and it makes the application code very neat, and tweaking with the configuration very easy.
有趣的替代配置文件格式:编写 scala 特征。然后,您的配置文件可以只是一个 scala 文件,您可以在服务器启动时对其进行编译和评估。
http://robey.lag.net//2012/03/26 /为什么-config.html
Interesting alternative config file format: write a scala trait. Your config file can then just be a scala file that you compile and evaluate when the server starts.
http://robey.lag.net//2012/03/26/why-config.html