From 04d9fb2b3584439797b49c6d152ba8b53812e51b Mon Sep 17 00:00:00 2001 From: linenhui023 Date: Thu, 25 Mar 2021 13:16:38 +0800 Subject: [PATCH 1/4] =?UTF-8?q?1:=E5=88=A0=E9=99=A4=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E6=B1=A0=E6=96=B9=E5=BC=8F=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 3 +- .../dowhat/monolith/MonolithApplication.java | 4 +- .../MonoSocketPoolAutoConfiguration.java | 78 ------------------- .../core/pool/MonoSocketObjectPool.java | 24 ------ .../pool/factory/MonoSocketObjectFactory.java | 44 ----------- .../monolith/core/pool/object/MonoSocket.java | 35 --------- ...lProperties.java => SocketProperties.java} | 22 ++---- .../dowhat/monolith/core/server/Server.java | 16 ++-- .../{SMTPSession.java => SmtpSession.java} | 52 ++++++++----- .../monolith/event/MessageListener.java | 21 ++--- .../web/service/impl/MessageServiceImpl.java | 20 +++-- src/main/resources/application.yaml | 23 +++--- src/main/resources/mapper/MessageMapper.xml | 2 +- src/main/resources/mapper/RecipientMapper.xml | 6 +- 14 files changed, 90 insertions(+), 260 deletions(-) delete mode 100644 src/main/java/cloud/dowhat/monolith/core/config/MonoSocketPoolAutoConfiguration.java delete mode 100644 src/main/java/cloud/dowhat/monolith/core/pool/MonoSocketObjectPool.java delete mode 100644 src/main/java/cloud/dowhat/monolith/core/pool/factory/MonoSocketObjectFactory.java delete mode 100644 src/main/java/cloud/dowhat/monolith/core/pool/object/MonoSocket.java rename src/main/java/cloud/dowhat/monolith/core/prop/{PoolProperties.java => SocketProperties.java} (40%) rename src/main/java/cloud/dowhat/monolith/core/session/{SMTPSession.java => SmtpSession.java} (73%) diff --git a/Dockerfile b/Dockerfile index cee8c32..da9a5ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,4 +8,5 @@ VOLUME /tmp # 将jar包添加到容器中并更名为app.jar ADD monolith-0.0.1.jar app.jar EXPOSE 8080 -ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] +#ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=11110","/app.jar"] diff --git a/src/main/java/cloud/dowhat/monolith/MonolithApplication.java b/src/main/java/cloud/dowhat/monolith/MonolithApplication.java index ad54547..4592c2e 100644 --- a/src/main/java/cloud/dowhat/monolith/MonolithApplication.java +++ b/src/main/java/cloud/dowhat/monolith/MonolithApplication.java @@ -3,6 +3,7 @@ package cloud.dowhat.monolith; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.retry.annotation.EnableRetry; import org.springframework.scheduling.annotation.EnableAsync; @@ -16,9 +17,8 @@ import org.springframework.scheduling.annotation.EnableAsync; public class MonolithApplication { public static void main(String[] args) { - SpringApplication.run(MonolithApplication.class, args); + ConfigurableApplicationContext run = SpringApplication.run(MonolithApplication.class, args); } - } diff --git a/src/main/java/cloud/dowhat/monolith/core/config/MonoSocketPoolAutoConfiguration.java b/src/main/java/cloud/dowhat/monolith/core/config/MonoSocketPoolAutoConfiguration.java deleted file mode 100644 index 3d78efd..0000000 --- a/src/main/java/cloud/dowhat/monolith/core/config/MonoSocketPoolAutoConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -package cloud.dowhat.monolith.core.config; - -import cloud.dowhat.monolith.core.pool.MonoSocketObjectPool; -import cloud.dowhat.monolith.core.pool.factory.MonoSocketObjectFactory; -import cloud.dowhat.monolith.core.pool.object.MonoSocket; -import cloud.dowhat.monolith.core.prop.PoolProperties; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.annotation.PreDestroy; - -/** - * @author linen - */ -@Configuration -public class MonoSocketPoolAutoConfiguration { - - private final PoolProperties poolProperties; - - private MonoSocketObjectPool pool; - - public MonoSocketPoolAutoConfiguration(PoolProperties poolProperties) { - this.poolProperties = poolProperties; - } - - - @ConditionalOnClass({MonoSocketObjectFactory.class}) - @Bean - protected MonoSocketObjectPool monoSocketObjectPool(){ - MonoSocketObjectFactory objectFactory = new MonoSocketObjectFactory(); - //设置对象池的相关参数 - GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig<>(); - poolConfig.setMaxIdle(poolProperties.getMaxIdle()); - poolConfig.setMaxTotal(poolProperties.getMaxTotal()); - poolConfig.setMinIdle(poolProperties.getMinIdle()); - poolConfig.setBlockWhenExhausted(true); - poolConfig.setTestOnBorrow(true); - poolConfig.setTestOnReturn(true); - poolConfig.setTestWhileIdle(true); - poolConfig.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30); - - poolConfig.setJmxEnabled(false); - //新建一个对象池,传入对象工厂和配置 - pool = new MonoSocketObjectPool(objectFactory,poolConfig); - initPool(poolProperties.getInitConn(),poolProperties.getMaxIdle()); - return pool; - } - - /** - * 初始化连接对象到池中 - * @param initConn 初始化数量 - * @param maxIdle 最大空闲数量 - */ - private void initPool(Integer initConn, Integer maxIdle) { - if (initConn <= 0) { - return; - } - - int size = Math.min(initConn, maxIdle); - for (int i = 0; i < size; i++) { - try { - pool.addObject(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - @PreDestroy - public void destroy(){ - if(pool!=null){ - pool.close(); - } - } - -} diff --git a/src/main/java/cloud/dowhat/monolith/core/pool/MonoSocketObjectPool.java b/src/main/java/cloud/dowhat/monolith/core/pool/MonoSocketObjectPool.java deleted file mode 100644 index 6dfc1a5..0000000 --- a/src/main/java/cloud/dowhat/monolith/core/pool/MonoSocketObjectPool.java +++ /dev/null @@ -1,24 +0,0 @@ -package cloud.dowhat.monolith.core.pool; - -import cloud.dowhat.monolith.core.pool.object.MonoSocket; -import org.apache.commons.pool2.PooledObjectFactory; -import org.apache.commons.pool2.impl.AbandonedConfig; -import org.apache.commons.pool2.impl.GenericObjectPool; -import org.apache.commons.pool2.impl.GenericObjectPoolConfig; - -/** - * @author linen - */ -public class MonoSocketObjectPool extends GenericObjectPool { - public MonoSocketObjectPool(PooledObjectFactory factory) { - super(factory); - } - - public MonoSocketObjectPool(PooledObjectFactory factory, GenericObjectPoolConfig config) { - super(factory, config); - } - - public MonoSocketObjectPool(PooledObjectFactory factory, GenericObjectPoolConfig config, AbandonedConfig abandonedConfig) { - super(factory, config, abandonedConfig); - } -} diff --git a/src/main/java/cloud/dowhat/monolith/core/pool/factory/MonoSocketObjectFactory.java b/src/main/java/cloud/dowhat/monolith/core/pool/factory/MonoSocketObjectFactory.java deleted file mode 100644 index e4dba90..0000000 --- a/src/main/java/cloud/dowhat/monolith/core/pool/factory/MonoSocketObjectFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -package cloud.dowhat.monolith.core.pool.factory; - -import cloud.dowhat.monolith.core.pool.object.MonoSocket; -import cloud.dowhat.monolith.core.prop.PoolProperties; -import cn.hutool.setting.dialect.Props; -import org.apache.commons.pool2.PooledObject; -import org.apache.commons.pool2.PooledObjectFactory; -import org.apache.commons.pool2.impl.DefaultPooledObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Configurable; - -import javax.annotation.Resource; - -/** - * @author linen - */ -@Configurable -public class MonoSocketObjectFactory implements PooledObjectFactory { - - @Override - public PooledObject makeObject() throws Exception { - return new DefaultPooledObject<>(new MonoSocket()); - } - - @Override - public void destroyObject(PooledObject pooledObject) throws Exception { - pooledObject.getObject().destroy(); - } - - @Override - public boolean validateObject(PooledObject pooledObject) { - return pooledObject.getObject().isActive(); - } - - @Override - public void activateObject(PooledObject pooledObject) throws Exception { - pooledObject.getObject().setActive(true); - } - - @Override - public void passivateObject(PooledObject pooledObject) throws Exception { - //todo - } -} diff --git a/src/main/java/cloud/dowhat/monolith/core/pool/object/MonoSocket.java b/src/main/java/cloud/dowhat/monolith/core/pool/object/MonoSocket.java deleted file mode 100644 index 7eda621..0000000 --- a/src/main/java/cloud/dowhat/monolith/core/pool/object/MonoSocket.java +++ /dev/null @@ -1,35 +0,0 @@ -package cloud.dowhat.monolith.core.pool.object; - -import lombok.Getter; -import lombok.Setter; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * @author LimOps - */ -public class MonoSocket extends ServerSocket { - - @Getter - @Setter - private Boolean active; - - public MonoSocket(int port) throws IOException { - super(port); - } - - public MonoSocket() throws IOException { - super(); - } - - - public void destroy(){ - - } - - public boolean isActive() { - return false; - } -} diff --git a/src/main/java/cloud/dowhat/monolith/core/prop/PoolProperties.java b/src/main/java/cloud/dowhat/monolith/core/prop/SocketProperties.java similarity index 40% rename from src/main/java/cloud/dowhat/monolith/core/prop/PoolProperties.java rename to src/main/java/cloud/dowhat/monolith/core/prop/SocketProperties.java index 40a961b..ff90abf 100644 --- a/src/main/java/cloud/dowhat/monolith/core/prop/PoolProperties.java +++ b/src/main/java/cloud/dowhat/monolith/core/prop/SocketProperties.java @@ -3,29 +3,19 @@ package cloud.dowhat.monolith.core.prop; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + /** * @author linen */ -@ConfigurationProperties(prefix = "monolith.socket.pool") -@Configuration + +@Component +@ConfigurationProperties(prefix = "monolith.socket") @Getter @Setter -public class PoolProperties { +public class SocketProperties { private Integer port; - private Integer timeout; - - private Integer maxCache; - - private Integer maxIdle; - - private Integer maxTotal; - - private Integer minIdle; - - private Integer initConn; - } diff --git a/src/main/java/cloud/dowhat/monolith/core/server/Server.java b/src/main/java/cloud/dowhat/monolith/core/server/Server.java index 3386e43..81a0a42 100644 --- a/src/main/java/cloud/dowhat/monolith/core/server/Server.java +++ b/src/main/java/cloud/dowhat/monolith/core/server/Server.java @@ -1,9 +1,7 @@ package cloud.dowhat.monolith.core.server; -import cloud.dowhat.monolith.core.pool.MonoSocketObjectPool; -import cloud.dowhat.monolith.core.pool.object.MonoSocket; -import cloud.dowhat.monolith.core.prop.PoolProperties; -import cloud.dowhat.monolith.core.session.SMTPSession; +import cloud.dowhat.monolith.core.prop.SocketProperties; +import cloud.dowhat.monolith.core.session.SmtpSession; import cn.hutool.core.thread.ThreadUtil; import lombok.AllArgsConstructor; import lombok.extern.log4j.Log4j2; @@ -23,20 +21,18 @@ import java.util.concurrent.atomic.AtomicReference; @AllArgsConstructor public class Server { - private final SMTPSession smtpSession; + private final SmtpSession smtpSession; - private final MonoSocketObjectPool pool; - - private final PoolProperties poolProperties; + private final SocketProperties socketProperties; @PostConstruct public void listener() { ThreadUtil.newExecutor(5,10).execute(()->{ - AtomicReference serverSocket = new AtomicReference<>(); + AtomicReference serverSocket = new AtomicReference<>(); //listener port:25 log.info(new Date() + "\t邮局服务已经启动"); try { - serverSocket.set(new MonoSocket(poolProperties.getPort())); + serverSocket.set(new ServerSocket(socketProperties.getPort())); for (; ; ) { smtpSession.setSocket(serverSocket.get().accept()); //todo: sleep 2s diff --git a/src/main/java/cloud/dowhat/monolith/core/session/SMTPSession.java b/src/main/java/cloud/dowhat/monolith/core/session/SmtpSession.java similarity index 73% rename from src/main/java/cloud/dowhat/monolith/core/session/SMTPSession.java rename to src/main/java/cloud/dowhat/monolith/core/session/SmtpSession.java index 32d70ce..fbf6965 100644 --- a/src/main/java/cloud/dowhat/monolith/core/session/SMTPSession.java +++ b/src/main/java/cloud/dowhat/monolith/core/session/SmtpSession.java @@ -19,7 +19,7 @@ import java.net.Socket; */ @Log4j2 @Component -public class SMTPSession { +public class SmtpSession { @Setter private Socket socket; @@ -28,31 +28,41 @@ public class SMTPSession { public void run() { try { - br = new BufferedReader( - new InputStreamReader(socket.getInputStream()) - ); - ps = new PrintStream( - socket.getOutputStream() - ); + synchronized (this) { + br = new BufferedReader( + new InputStreamReader(socket.getInputStream()) + ); + ps = new PrintStream( + socket.getOutputStream() + ); + } doWelcome(); String line; + + int num = 0; + char ch; + while ((num = br.read()) != -1) { + ch = (char) num; + System.out.print(ch); + log.info("数据:{}", ch); + } line = br.readLine(); while (line != null) { log.info("\nEmail 协议信息:{}", line); String command = line.substring(0, 4).trim(); if (command.equalsIgnoreCase(SmtpEnum.HELO.getCode()) || command.equalsIgnoreCase(SmtpEnum.EHLO.getCode())) { doHello(); - } else if (command.equalsIgnoreCase(SmtpEnum.RSET.getCode())) + } else if (command.equalsIgnoreCase(SmtpEnum.RSET.getCode())) { doRset(); - else if (command.equalsIgnoreCase(SmtpEnum.MAIL.getCode())) + } else if (command.equalsIgnoreCase(SmtpEnum.MAIL.getCode())) { doMail(); - else if (command.equalsIgnoreCase(SmtpEnum.RCPT.getCode())) + } else if (command.equalsIgnoreCase(SmtpEnum.RCPT.getCode())) { doRcpt(); - else if (command.equalsIgnoreCase(SmtpEnum.DATA.getCode())) + } else if (command.equalsIgnoreCase(SmtpEnum.DATA.getCode())) { doData(); - else if (command.equalsIgnoreCase(SmtpEnum.NOOP.getCode())) + } else if (command.equalsIgnoreCase(SmtpEnum.NOOP.getCode())) { doNoop(); - else if (command.equalsIgnoreCase(SmtpEnum.QUIT.getCode())) { + } else if (command.equalsIgnoreCase(SmtpEnum.QUIT.getCode())) { doQuit(); break; } @@ -65,7 +75,10 @@ public class SMTPSession { try { br.close(); ps.close(); - socket.close(); + synchronized (this) { + socket.close(); + log.info("socket current关闭..."); + } } catch (IOException e) { ps.println("500 ERROR"); log.error("It is possible that an error occurred when the stream was closed....", e); @@ -96,7 +109,7 @@ public class SMTPSession { String line = null; StringBuilder stringBuffer = new StringBuilder(); while ((line = br.readLine()) != null) { - if (line.equals(".")) { + if (".".equals(line)) { break; } stringBuffer.append(line).append("\r"); @@ -106,12 +119,14 @@ public class SMTPSession { //发布入库事件 MimeMessage mimeMessage = MimeMessageUtils.createMimeMessage(null, new ByteArrayInputStream(stringBuffer.toString().getBytes())); MimeMessageParser parser = new MimeMessageParser(mimeMessage); + log.info("发布事件=============>> 1 step"); MessageEventParam messageEventParam = new MessageEventParam(); messageEventParam.setParser(parser); MessageEvent event = new MessageEvent(messageEventParam); MonolithEventManager.publishEvent(event); + log.info("发布事件=============>> 2 step"); } catch (Exception e) { - log.error("publish event error",e); + log.error("publish event error", e); ps.println("500 ERROR"); } ps.println("250 OK"); @@ -158,7 +173,8 @@ public class SMTPSession { * 第一次传递 */ private void doWelcome() { - ps.println("220 Welcome to my smtp server"); - ps.flush(); +// ps.println("220 mail.gitee.ltd Anti-spam GT for Coremail System "); + ps.println("220 Welcome to SMTP server!"); +// ps.flush(); } } diff --git a/src/main/java/cloud/dowhat/monolith/event/MessageListener.java b/src/main/java/cloud/dowhat/monolith/event/MessageListener.java index 9629707..fba6fd2 100644 --- a/src/main/java/cloud/dowhat/monolith/event/MessageListener.java +++ b/src/main/java/cloud/dowhat/monolith/event/MessageListener.java @@ -25,8 +25,8 @@ public class MessageListener { /** * save message to db + * * @param source cloud.dowhat.monolith.event.MessageEventParam - * @throws Exception error */ @Async @EventListener(MessageEvent.class) @@ -39,16 +39,17 @@ public class MessageListener { String from = null; try { from = parser.getFrom(); - message.setSenderAddress(from); - String subject = parser.getSubject(); - message.setSubject(subject); - String plainContent = parser.parse().getPlainContent(); - message.setContent(plainContent); - String receiveAddresses = MailUtil.getReceiveAddresses(parser.getMimeMessage(), null); - log.info("\nEmail Info:{from:{}\nto:{}\nsubject:{}\ncontent:{}\n}", from, receiveAddresses, subject, plainContent); - iMessageService.save(message, receiveAddresses.split(ADDRESSES_REGEX)); + message.setSenderAddress(from); + String subject = parser.getSubject(); + message.setSubject(subject); + String plainContent = parser.parse().getPlainContent(); + message.setContent(plainContent); + String receiveAddresses = MailUtil.getReceiveAddresses(parser.getMimeMessage(), null); + log.info("\nEmail Info:{from:{}\nto:{}\nsubject:{}\ncontent:{}\n}", from, receiveAddresses, subject, plainContent); + log.info("发布事件=============>> OK"); + iMessageService.save(message, receiveAddresses.split(ADDRESSES_REGEX)); } catch (Exception e) { - log.error("save message to db error...",e); + log.error("save message to db error...", e); } } diff --git a/src/main/java/cloud/dowhat/monolith/web/service/impl/MessageServiceImpl.java b/src/main/java/cloud/dowhat/monolith/web/service/impl/MessageServiceImpl.java index 34a0415..9dfe514 100644 --- a/src/main/java/cloud/dowhat/monolith/web/service/impl/MessageServiceImpl.java +++ b/src/main/java/cloud/dowhat/monolith/web/service/impl/MessageServiceImpl.java @@ -65,22 +65,30 @@ public class MessageServiceImpl implements IMessageService { MessageRecipient messageRecipient = new MessageRecipient(); messageRecipient.setMessageId(message.getId()); String address = addresses[i]; - messageRecipient.setRecipientId(addressAndId.get(address)); + messageRecipient.setRecipientId(getResultAddress(addressAndId, address)); messageRecipient.setType(EmailTypeEnum.getCodeByAddressIndex(i)); iMessageRecipientMapper.insert(messageRecipient); //send mail content to html CopyOnWriteArraySet> concurrentHashMapCopyOnWriteArraySet = WebSocketServer.getWEB_SOCKET_SERVERS(); concurrentHashMapCopyOnWriteArraySet.forEach(webSocketServerConcurrentHashMap -> { try { - if (webSocketServerConcurrentHashMap.get(address) != null) { - log.info("publish ws_query_string:{}", address); - WebSocketServer webSocketServer = webSocketServerConcurrentHashMap.get(address); - webSocketServer.sendMessage(JSONObject.toJSONString(iMessageMapper.getMessages(address).get(0))); - } + log.info("publish ws_query_string:{}", address); + WebSocketServer resultAddress = getResultAddress(webSocketServerConcurrentHashMap, address); + resultAddress.sendMessage(JSONObject.toJSONString(iMessageMapper.getMessages(address).get(0))); } catch (IOException e) { log.error("send msg to html error...", e); } }); } } + + private T getResultAddress(Map params, String email) { + for (Map.Entry param : params.entrySet()) { + String key = param.getKey(); + if (key.indexOf(email) > -1) { + return param.getValue(); + } + } + throw new RuntimeException("邮箱格式错误!"); + } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index b240bc9..9900d5b 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,14 +1,14 @@ server: - port: ${port:8080} + port: ${port:11110} spring: application: name: monilith datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/monolith?characterEncoding=utf8&useUnicode=true&verifyServerCertificate=false&useSSL=false&requireSSL=false&serverTimezone=UTC + url: jdbc:mysql://8.136.23.192:11106/monolith?characterEncoding=utf8&useUnicode=true&verifyServerCertificate=false&useSSL=false&requireSSL=false&serverTimezone=UTC type: com.zaxxer.hikari.HikariDataSource - username: root - password: '123456' + username: monolith + password: 'xRDapDFTDdp4fF2T' hikari: minimum-idle: 5 # 空闲连接存活最大时间,默认600000(10分钟) @@ -24,6 +24,7 @@ spring: # 数据库连接超时时间,默认30秒,即30000 connection-timeout: 30000 connection-test-query: SELECT 1 + validation-timeout: 5000 mybatis: @@ -31,15 +32,13 @@ mybatis: monolith: socket: - pool: - port: 25 - max_total: 60 - max_idle: 50 - min_idle: 10 - max_cache: 256 - timeout: 50000 - init_conn: 10 + port: 25 mail: host: host: 'mail.gitee.ltd' + +logging: + level: + cloud.dowhat.monolith.web.mapper: debug + diff --git a/src/main/resources/mapper/MessageMapper.xml b/src/main/resources/mapper/MessageMapper.xml index e12d2b5..9626cda 100644 --- a/src/main/resources/mapper/MessageMapper.xml +++ b/src/main/resources/mapper/MessageMapper.xml @@ -19,7 +19,7 @@ LEFT JOIN t_recipient AS r ON mr.recipient_id = r.id WHERE m.del = 0 AND r.del = 0 - AND r.recipient_address = #{address} + AND r.recipient_address like concat('%',#{address},'%') order by m.create_time desc diff --git a/src/main/resources/mapper/RecipientMapper.xml b/src/main/resources/mapper/RecipientMapper.xml index 08abfdb..da1718f 100644 --- a/src/main/resources/mapper/RecipientMapper.xml +++ b/src/main/resources/mapper/RecipientMapper.xml @@ -26,9 +26,9 @@ where recipient_address = #{ew.recipientAddress};