聲明:本文來源於MLDN培訓視頻的課堂筆記,寫在這里只是為了方便查閱。
1、概念:SpringBoot 服務整合
2、背景
在進行項目開發的時候經常會遇見以下的幾個問題:需要進行郵件發送、定時的任務調度、系統的監控處理,實際上這些操 作都可以通過 SpringBoot 進行整合操作。
2.1、SpringBoot 整合郵件服務
如果要進行郵件的整合處理,那么你一定需要有一個郵件服務器,實際上 java 本身提供有一套 JavaMail 組件以實現郵件服務器的搭建,但是這個搭建的服務器意義不大,因為你現在搭建完成了,向一些大型的站點發送一封郵件,若干小時你就會被拉黑, 如果不想拉黑彼此之間就做一個白名單即可。
那么如果說現在自己搭建郵件服務器不行,就可以考慮使用 QQ 郵件服務、網易郵件服務,本次可以申請一個 QQ 郵件服務器,如果要申請你一定要登錄你自己的 QQ 郵箱。
1、 如果要想實現郵件的發送服務,則首先要導入一個依賴的支持庫:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
2、 修改項目中的 application.yml 配置文件,實現郵件的配置:
spring:
messages:
basename: i18n/Messages,i18n/Pages
mail:
host: smtp.qq.com
username: 你自己的用戶名,110@qq.com
password: xxxxx
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
mail.smtp.starttls.required: true
3、 編寫測試類,直接調用 mail 服務:
package cn.study.microboot; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @SpringBootTest(classes = StartSpringBootMain.class) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration public class TestMail { @Resource private JavaMailSender javaMailSender ; @Test public void testSendMail() { SimpleMailMessage message = new SimpleMailMessage() ; // 要發送的消息內容 message.setFrom("你自己的郵箱地址,444@qq.com"); message.setTo("接收者的郵箱地址,555@qq.com"); message.setSubject("測試郵件)"); message.setText("好好學習,天天向上"); this.javaMailSender.send(message); } }
你如果要是個人玩玩還可以,如果要進行海量發送,騰訊不會讓你得逞的,你得再去申請企業的郵箱,如果現在覺得騰訊郵 箱不能夠滿足於你的要求,你可以考慮使用阿里雲服務。
2.2、定時調度
所有的系統開發里面定時調度絕對是一個核心的話題,對於定時調度的實現在實際開發之中可以使用:TimerTask、Quartz、 SpringTask 配置,實際上這里面最簡單的配置就是 Spring 自己所提供的 Task 處理。
1、 如果要想實現定時調度,只需要配置一個定時調度的組件類即可:
package cn.study.microboot.task; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class MyScheduler { @Scheduled(fixedRate = 2000) // 采用間隔調度,每2秒執行一次 public void runJobA() { // 定義一個要執行的任務 System.out.println("【*** MyTaskA - 間隔調度 ***】" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") .format(new Date())); } @Scheduled(cron = "* * * * * ?") // 每秒調用一次 public void runJobB() { System.err.println("【*** MyTaskB - 間隔調度 ***】" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") .format(new Date())); } }
2、 如果現在要想執行此任務,那么還需要有一個基本的前提:你的程序啟動類上一定要啟用調度處理。
package cn.study.microboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication // 啟動SpringBoot程序,而后自帶子包掃描 @EnableScheduling // 啟用間隔調度 public class StartSpringBootMain { public static void main(String[] args) throws Exception { SpringApplication.run(StartSpringBootMain.class, args); } }
這個時候所實現的任務調度只是串行任務調度,也就是說所有的任務是一個一個執行的處理方式,那么如果現在有一個任務 所花費的時間特別的長,則其它的任務都會積壓,實際開發之中很明顯這種處理是不可能存在的。
3、 如果要想啟用並行的調度處理,則一定要准備出一個線程調度池,進行一個線程調度的配置類:
package cn.study.microboot.config; import java.util.concurrent.Executors; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; @Configuration // 定時調度的配置類一定要實現指定的父接口 public class SchedulerConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { // 開啟一個線程調度池 taskRegistrar.setScheduler(Executors.newScheduledThreadPool(100)); } }
2.3、Actuator 監控
對於 SpringBoot 中的服務的監控在 SpringBoot 開發框架之中提供有一個 Actuator 監控程序,但是這個監控程序在很多的時候 使用有一些矛盾,對於此類的信息服務,一般而言會有兩類信息:
· 第一類是由系統直接提供好的信息,這個需要關閉安全控制;
· 第二類是由用戶定義的,希望可以返回固定的一些信息,例如:版本、服務名稱等。
1、 如果現在要想在代碼之中啟用 actuator 服務,那么首先一定要進行開發包的配置;
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2、 此時配置此依賴包的項目就具有了監控的操作能力,但是這個能力無法直接體現,如果現在要想打開默認的系統的這些監控 信息,則需要修改 application.yml 配置文件,關閉掉當前的安全配置項:
server:
port: 80
management:
security:
enabled: false # 現在關閉系統的安全配置
3、 但是如果現在將系統的安全配置關閉了之后,那么此時你的系統的服務信息就有可能被任何人看見,那么不希望被所有人看 見,同時也希望所有的人可以看見一些能夠看見的提示信息,所以在這樣的狀態下,就需要去考慮自定義一些服務信息出現。例如, 現在先進行健康信息的配置;
范例:定義一個健康配置類
package cn.study.microboot.actuator; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Component public class MyHealthIndicator implements HealthIndicator { @Override public Health health() { return Health.down().withDetail("info", "老子還活着!").build(); } }
但是發現這種健康的信息配置是需要打開安全策略之后才能夠發現一些更加詳細的內容,而如果開啟了安全策略之后可以看 見的信息只能夠是一些基礎的狀態:UP(存活)、DOWN(關閉)。
package cn.study.microboot.actuator; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; @Component public class MyHealthIndicator implements HealthIndicator { @Override public Health health() { int errorCode = 100 ; // 這個錯誤的碼是通過其它程序獲得的 if (errorCode != 0) { return Health.down().withDetail("Error Code", errorCode).build(); } return Health.up().build() ; } }
4、 除了健康之外,還有一項數據很重要,就是一些服務的信息(/info),而這些服務的信息可以直接通過 application.yml 文件配 置,修改 application.yml 要按照指定的格式完成:
· 對於這樣的配置信息最好的方式就是進行 pom.xml 文件的讀取,所以如果要想實現這種關聯操作,則必須修改 microboot 項目中的 pom.xml 文件,追加有一個訪問的插件:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimiter>$</delimiter> </delimiters> </configuration> </plugin>
· 修改 resources 中的訪問處理:
<resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.yml</include> <include>**/*.xml</include> <include>**/*.tld</include> <include>**/*.p12</include> <include>**/*.conf</include> </includes> <filtering>true</filtering> </resource>
· 修改 application.yml 配置文件,追加詳細信息
info:
app.name: mldn-microboot
app.version: v1.0.0
company.name: www.mldn.cn
pom.artifactId: $project.artifactId$
pom.version: $project.version$
5、 由於在開發之中這種提示信息會成為微服務的重要組成部分,所以很多時候如果重復進行application.yml 配置文件的定義,那么會比較麻煩, 最簡單的做法直接做一個配置程序類進行信息的配置。
package cn.study.microboot.actuator; import org.springframework.boot.actuate.info.Info.Builder; import org.springframework.stereotype.Component; import org.springframework.boot.actuate.info.InfoContributor; @Component public class ProjectInfoContributor implements InfoContributor { @Override public void contribute(Builder builder) { builder.withDetail("company.name", "study") ; builder.withDetail("version", "V1.0") ; builder.withDetail("author", "sss") ; } }