This method is only suitable for smaller projects, such as only one or two servers, and the configuration file can be modified directly. For example, Spring mvc is deployed in the form of war packages, and the configuration files in resources can be directly modified. If it is a Spring boot project and you want to use this method, you need to refer to an external editable file, such as a fixed directory, because most spring boot is deployed in jar packages, and the configuration files you enter the package cannot be modified directly. If it is a relatively large project, it is best to use a configuration center, such as Ctrip's Apollo, Consul, etc.
Original way
The original method refers to repackaging and releasing the server every time you want to modify the configuration.
Suppose we use spring mvc to develop, and after the development is completed, we will form a war package and deploy it to tomcat. If we modify a SMS interface address at this time.
We need to do the following:
1. Open the configuration file and modify the configuration information;
2. Compile and package;
3. Stop tomcat and delete the old project directory;
4. Put the new war package in webapps and start tomcat.
Of course, you can directly find the configuration file of this project in tomcat and then modify it, but you also need to restart tomcat.
If you just do development or testing, it is certainly acceptable to be a bit of a waste of time. So, I don’t want to waste time or restart tomcat, is there any way? This is the turn of this article to introduce.
WatchService method
Java provides a WatchService interface, which uses the operating system's own file monitor to monitor directories and files. When the monitored object changes, there will be signal notifications, so that changes can be discovered efficiently.
The general principle of this method is: first, new a monitor (WatchService) according to the operating system, then select the directory or file where the configuration file to be monitored, and then subscribe to the events to be monitored, such as creating, deleting, editing, and finally registering the monitor with the monitored location. Once the event corresponding to the subscribed event is triggered, the corresponding logic is executed.
Let's start with the code. This is in a spring mvc project, and the resources directory is monitored.
@Repositorypublic class ConfigWatcher { private static final Logger logger = LoggerFactory.getLogger(ConfigWatcher.class); private static WatchService watchService; @PostConstruct public void init() { logger.info("Start Configuration File Monitor"); try { watchService = FileSystems.getDefault().newWatchService(); URL url = ConfigWatcher.class.getResource("/"); Path path = Paths.get(url.toURI()); path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE); } catch (Exception e1) { e1.printStackTrace(); } /** * Start the monitoring thread*/ Thread watchThread = new Thread(new WatchThread()); watchThread.setDaemon(true); watchThread.start(); /** Register to close the hook*/ Thread hook = new Thread(new Runnable() { @Override public void run() { try { watchService.close(); } catch (IOException e) { e.printStackTrace(); } } }); Runtime.getRuntime().addShutdownHook(hook); } public class WatchThread implements Runnable { @Override public void run() { while (true) { try { // Try to get the changes in the monitoring pool, if not, wait for WatchKey watchKey = watchService.take(); for (WatchEvent<?> event : watchKey.pollEvents()) { String editFileName = event.context().toString(); logger.info(editFileName); /** * Reload configuration*/ } watchKey.reset();//To complete monitoring, you need to reset the monitor once} catch (Exception e) { e.printStackTrace(); } } } }}The code is very simple and you can understand it at a glance. When the project starts, use FileSystems.getDefault().newWatchService() to create a WatchService, which is based on the operating system. Then get the URL of the resources directory, and get the Path, then call the register method of the Path object, register the monitor, and subscribe to edit and create events. Events are defined in the StandardWatchEventKinds class, and there are four types:
1. StandardWatchEventKinds#OVERFLOW
2. StandardWatchEventKinds#ENTRY_CREATE
3. StandardWatchEventKinds#ENTRY_DELETE
4. StandardWatchEventKinds#ENTRY_MODIFY
Then a WatchThread thread is started separately to handle the change logic, and the take() method is called in a while infinite loop until a change occurs. Once the configuration file we monitor changes, our logic is called to reload the configuration. In addition, after each change occurs, the watchKey.reset() method must be called to reset the monitor.
Finally, you need to register a hook, and you can turn off the monitor when jvm is closed.
With this method, when we have some configuration changes, we can directly go to tomcat to modify the configuration file, and it can take effect without restarting.
This article mainly introduces this method, which is also mentioned above. This method is only suitable for very simple projects. For large-scale projects, a more advanced method is required.
How to configure the center
When the complexity of the project becomes higher, the configuration changes take effect in real time, grayscale release, divided into environments, cluster management configurations, and complete permissions and audit mechanisms may all become issues to be considered in the project. At this time, relying solely on the configuration files will seem incompetent.
Currently, the most commonly used configuration centers include etcd, zookeeper, disconf, Apollo, etc. Disconf and Apollo are both ready-to-use, with complete functions and supporting UI. And etcd and zookeeper require some custom development.
Students can choose according to their needs, and more detailed content can be searched and practiced by themselves.