javax.mail.MessagingException: Could not connect to SMTP host: smtp.163.com, port: 465, response: -1 at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1960) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:642) at javax.mail.Service.connect(Service.java:295) at azkaban.utils.JavaxMailSender.connect(JavaxMailSender.java:34) at azkaban.utils.EmailMessage.connectToSMTPServer(EmailMessage.java:220) at azkaban.utils.EmailMessage.retryConnectToSMTPServer(EmailMessage.java:230) at azkaban.utils.EmailMessage.sendEmail(EmailMessage.java:213) at azkaban.utils.Emailer.sendEmail(Emailer.java:220) at azkaban.utils.Emailer.alertonSuccess(Emailer.java:153) at azkaban.executor.ExecutionControllerUtils.alertUseronFlowFinished(ExecutionControllerUtils.java:140) at azkaban.executor.ExecutionFinalizer.finalizeFlow(ExecutionFinalizer.java:97) at azkaban.executor.RunningExecutionsUpdater.updateExecutions(RunningExecutionsUpdater.java:130) at azkaban.executor.RunningExecutionsUpdaterThread.run(RunningExecutionsUpdaterThread.java:54) 2022/01/08 15:09:01.807 +0800 ERROR [EmailMessage] [Azkaban] Connecting to SMTP server failed, attempt: 4最受用的感触
这段时间搭建了离线数仓,调度器用的是Azkaban,在最后的环节中,遇到了Azkaban报警邮件发不出的问题。为了解决这个问题,花去了半天时间:
1)阿里云22端口未开放:
因为我的hadoop集群环境是在阿里云上搭建的,经过查资料获悉阿里云为了安全把22端口禁用了。官方给出的替换方案是用465端口
2)直接修改Azkaban的配置文件为465端口:
我通过查看Azkaban-web源码,确实支持配置文件修改端口,那我加上端口重新起,重新执行任务,谁知道还是报错。
mail.port=465
3)通过javaMail排除邮箱的问题
开始排查,开始怀疑我的163邮箱有问题,随手写了个javaMail,经过测试邮箱没问题
package com.sonkwo.javamail; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.Date; import java.util.Properties; public class TestJavaMail { // 发件人的 邮箱 和 密码(替换为自己的邮箱和密码) // PS: 某些邮箱服务器为了增加邮箱本身密码的安全性,给 SMTP 客户端设置了独立密码(有的邮箱称为“授权码”), // 对于开启了独立密码的邮箱, 这里的邮箱密码必需使用这个独立密码(授权码)。 public static String myEmailAccount = "xxxx@163.com"; public static String myEmailPassword = "xxxxxxx"; // 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com // 网易163邮箱的 SMTP 服务器地址为: smtp.163.com public static String myEmailSMTPHost = "smtp.163.com"; // 收件人邮箱(替换为自己知道的有效邮箱) public static String receiveMailAccount = "yyyyyy@qq.com"; public static void main(String[] args) throws Exception { // 1. 创建参数配置, 用于连接邮件服务器的参数配置 Properties props = new Properties(); // 参数配置 props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求) props.setProperty("mail.smtp.host", myEmailSMTPHost); // 发件人的邮箱的 SMTP 服务器地址 props.setProperty("mail.smtp.auth", "true"); // 需要请求认证 // PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启), // 如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误, // 打开下面 之间的注释代码, 开启 SSL 安全连接。 // 2. 根据配置创建会话对象, 用于和邮件服务器交互 Session session = Session.getDefaultInstance(props); session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log // 3. 创建一封邮件 MimeMessage message = createMimeMessage(session, myEmailAccount, receiveMailAccount); // 4. 根据 Session 获取邮件传输对象 Transport transport = session.getTransport(); // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错 // // PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log, // 仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误 // 类型到对应邮件服务器的帮助网站上查看具体失败原因。 // // PS_02: 连接失败的原因通常为以下几点, 仔细检查代码: // (1) 邮箱没有开启 SMTP 服务; // (2) 邮箱密码错误, 例如某些邮箱开启了独立密码; // (3) 邮箱服务器要求必须要使用 SSL 安全连接; // (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务; // (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。 // // PS_03: 仔细看log, 认真看log, 看懂log, 错误原因都在log已说明。 transport.connect(myEmailAccount, myEmailPassword); // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人 transport.sendMessage(message, message.getAllRecipients()); // 7. 关闭连接 transport.close(); } public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail) throws Exception { // 1. 创建一封邮件 MimeMessage message = new MimeMessage(session); // 2. From: 发件人 message.setFrom(new InternetAddress(sendMail, "某宝网", "UTF-8")); // 3. To: 收件人(可以增加多个收件人、抄送、密送) message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "XX用户", "UTF-8")); // 4. Subject: 邮件主题 message.setSubject("打折钜惠", "UTF-8"); // 5. Content: 邮件正文(可以使用html标签) message.setContent("XX用户你好, 今天全场5折, 快来抢购, 错过今天再等一年。。。", "text/html;charset=UTF-8"); // 6. 设置发件时间 message.setSentDate(new Date()); // 7. 保存设置 message.saveChanges(); return message; } }
4)运维排除阿里云465端口的问题
我反馈给运维的同学说我的163邮箱没问题,随后他就写了程序测试465端口确实能发出邮件。这样就断定是Azkaban组件的问题,修改了465端口后没有生效。
5)下定决心,编译Azkaban
一想到重新编译软件,感觉要下载很多包,要报很多错误,有很大的挫败感。但是想想,现在也没有其他办法了,试试呗。
6)编译完成,感觉很有收获
没想到Azkaban编译时如此的简单,当编译成功的时候也是下班的时间点,很是激动,那就让我们开始吧。
1.基础环境准备1)下载源码
因为github下载很慢,所以我再码云上找了一份源码下载的。
[xxx@xxx software]$ git clone https://gitee.com/leechi78/azkaban.git
2)查看该版本azkaban对应的gradle版本为gradle-5.0-all.zip
[xxx@xxx software]$ cd azkaban [xxx@xxx azkaban]$ cat ./gradle/wrapper/gradle-wrapper.properties
#
# Copyright 2018 linkedIn Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
distributionbase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# To change gradle version, use (rather than changing the line below):
# ./gradlew wrapper --gradle-version=
#
# e.g.
# ./gradlew wrapper --gradle-version=5.0
#
distributionUrl=https://services.gradle.org/distributions/gradle-5.0-all.zip
zipStorebase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
3)下载gradle
wget https://services.gradle.org/distributions/gradle-5.0-all.zip
xxx@xxx wrapper]$ cd /opt/software/azkaban/gradle/wrapper
xxx@xxx wrapper]$ cp /opt/software/gradle-5.0-all.zip ./
4)解压到指定目录
[xxx@xxx software]$ unzip -o gradle-5.0-all.zip -d /opt/module/
5)配置环境变量
[xxx@xxx ~]$ sudo vim /etc/profile.d/my_env.sh
添加
# GRADLE_USER_HOME
export GRADLE_USER_HOME=/opt/module/gradle-5.0
export PATH=$PATH:$GRADLE_USER_HOME/bin
使配置生效
[xxx@xxx ~]$ source /etc/profile2.修改配置文件
1)修改配置文件 gradle-wrapper.properties 中的 distributionUrl 属性,指明使用本地的 gradle
[sonkwo@sonkwo-bj-data001 azkaban]$
vim ./gradle/wrapper/gradle-wrapper.properties
distributionUrl=distributionUrl=gradle-5.0-all.zip
zipStorebase=GRADLE_USER_HOME
2)若未安装Git,则安装;否则,免安装。
[xxx@xxx software]$ yum install git
3)在 azkaban-common/src/main/java/azkaban/utils/EmailMessage.java中的sendEmail()方法里,加入如下代码:
[xxx@xxx azkaban]$ vim azkaban-common/src/main/java/azkaban/utils/EmailMessage.java
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.socketFactory.port", "465");
[xxx@xxx azkaban]$ vim azkaban-common/src/main/java/azkaban/jobExecutor/ProcessJob.java
1)开始编译
[xxx@xxx azkaban]$ ./gradlew build installDist -x test
2)编译报错
[xxx@xxx azkaban]$ ./gradlew build installDist -x test
Downloading file:/opt/software/azkaban/gradle/wrapper/gradle-5.0-all.zip
...........................................................................................................................
Unzipping /opt/module/gradle-5.0/wrapper/dists/gradle-5.0-all/8subxm1j4sfxdrf9xyahjxjyp/gradle-5.0-all.zip to /opt/module/gradle-5.0/wrapper/dists/gradle-5.0-all/8subxm1j4sfxdrf9xyahjxjyp
Set executable permissions for: /opt/module/gradle-5.0/wrapper/dists/gradle-5.0-all/8subxm1j4sfxdrf9xyahjxjyp/gradle-5.0/bin/gradle
Welcome to Gradle 5.0!
Here are the highlights of this release:
- Kotlin DSL 1.0
- Task timeouts
- Dependency alignment aka BOM support
- Interactive `gradle init`
For more details see Gradle 5.0 Release Notes
Starting a Gradle Daemon (subsequent builds will be faster)
Configuration on demand is an incubating feature.
> Task :az-exec-util:linkMainExecutable FAILED
> Task :az-core:compileJava
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :azkaban-web-server:restliTemplateGenerator
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See SLF4J Error Codes for further details.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':az-exec-util:linkMainExecutable'.
> Could not find linker 'g++' in system path.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at Gradle | Search for Help with Gradle
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See Command-Line Interface
BUILD FAILED in 2m 27s
19 actionable tasks: 19 executed
sudo yum install gcc gcc-c++
2)重新编译
[xxx@xxx azkaban]$ ./gradlew build installDist -x test
1)获取azkaban-exec-server.tar.zip安装包
[xxx@xxx distributions]$ cd /opt/software/azkaban/azkaban-exec-server/build/distributions
2)获取azkaban-web-server.tar.zip安装包
[xxx@xxx distributions]$ cd /opt/software/azkaban/azkaban-web-server/build/distributions
3)获取azkaban-db.tar.zip安装包
[xxx@xxx distributions]$ cd /opt/software/azkaban/azkaban-db/build/distributions
略
6.测试发送报警邮件验证完成
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)