最近公司準備搞分佈式,需要將原代碼按功能等一個個抽離出來,我負責弄郵箱短信部分,經歷了半個月的折磨,總算搞出來了,這裏做個總結,有許多之前沒弄過的,算是由0到1的一個過程。
整個思路過程如下:
比較簡單的,對外暴露的僅僅只是api接口,內部最重要的是一個實體類,用於存儲需上傳的數據,再發送給mq,然後消費mq中的信息。
這其中有幾個問題需要總結的,算是這個過程中卡得我難受的點。
第一:設計上,對外暴露的api接口只有存儲對象和mq發送方法,這裏是一個小技巧,邏輯處理封裝起來,並不對外提供服務。存儲對象類設計上還是有點意思的,用到了內部類,這裏記錄下來,以後做參考:
package cn.coralglobal.message.api.service;
import cn.coralglobal.message.api.exception.MessageCenterBuilderException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
/**
* @Description: 消息主體對象
* @Author chenjianwen
* @Date 2020-03-25
**/
@Data
@Slf4j
public class MessageSubject implements Serializable {
private static final long serialVersionUID = 4901512199571414865L;
/**
* 發送時間
*/
private long timestamp = System.currentTimeMillis();
/**
* 模版名稱
*/
private String templateName;
/**
* 模版code
*/
private String templateCode;
/**
* 替換文本,和模版中的佔位符嚴格一一對應
*/
private String[] replace;
/**
* 消息受衆(可以是userId或者用戶手機號或郵箱)
*/
private String[] users;
/**
* 發送消息的站臺(coralglobal或crm或其他)
*/
private String platform;
public MessageSubject(){}
public MessageSubject(Builder builder){
setTimestamp(builder.timestamp);
setTemplateName(builder.templateName);
setTemplateCode(builder.templateCode);
setReplace(builder.replace);
setUsers(builder.users);
setPlatform(builder.platform);
}
public static Builder newBuilder(){
return new Builder();
}
public static Builder newBuilder(MessageSubject ms){
Builder b = new Builder();
b.timestamp = ms.getTimestamp();
b.templateName = ms.getTemplateName();
b.templateCode = ms.getTemplateCode();
b.replace = ms.getReplace();
b.users = ms.getUsers();
b.platform = ms.getPlatform();
return b;
}
public static final class Builder{
private long timestamp;
private String templateName;
private String templateCode;
private String[] replace;
private String[] users;
private String platform;
private Builder(){}
public Builder timestamp(long timestamp){
this.timestamp = timestamp;
return this;
}
public Builder name(String templateName){
this.templateName = templateName;
return this;
}
public Builder template(String code) throws MessageCenterBuilderException {
if(code == null || "".equals(code)){
log.error("message-center-api|MessageSubject|template(String code)|模版編碼不能爲空");
throw new MessageCenterBuilderException("message-center|MessageSubject|template(String code)|模版編碼不能爲空");
}
this.templateCode = code;
return this;
}
public Builder replace(String... replace){
this.replace = replace;
return this;
}
public Builder users(String... users){
this.users = users;
return this;
}
public Builder platform(String platform){
this.platform = platform;
return this;
}
public MessageSubject build() throws MessageCenterBuilderException {
if(this.templateCode == null || "".equals(this.templateCode)){
log.error("message-center-api|MessageSubject|build()|templateCode不能爲空");
throw new MessageCenterBuilderException("message-center-api|MessageSubject|build()|templateCode不能爲空");
}
return new MessageSubject(this);
}
}
}
第二:用mq發送數據的時候,先將數據序列化成字節數據會好點,用下面這個方法:
com.fasterxml.jackson.databind.ObjectMapper;
其maven依賴是:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
然後監聽器那邊轉換一下即可:
第三: 由於它是一個單獨的服務,因此最終需要打成jar到我們公司本地的私服並生成maven依賴,以供其他的項目使用。所以需要分兩步完成:
(1)我需要現在本地repository倉庫生成jar,那問題來了,如何在本地生成jar,這裏涉及到了maven的三個命令:
mvn clean package 在項目目錄下的target目錄下生成jar
mvn clean install 打包jar到target目錄下,且打包到本地repository
mvn clean deploy 打包jar到target目錄下,且打包到本地repository,且打包到遠程repository
這裏在本地倉庫測試,因此使用mvn clean install,或者直接在idea上的maven可視化操作,如下:
(2)在公司私服生成jar有點麻煩,花了很多時間才搞定,首先,需要在settings.xml中<servers></servers>標籤對中添加本地私服的服務器用戶名和密碼,如下:
然後在項目中的pom.xml文件中添加如下標籤對:
然後使用mvn clean deploy命令就能將服務打成jar包上傳到本地私服。
(2)如何引用本地私服的maven依賴,除了在pom.xml中引用<dependency></dependency>依賴之外,還需要引用本地私服倉庫的地址,如下:
這樣,就能引用本地私服倉庫的maven的jar包了。