
# 使用集群外客户端连接Spark端口失败
#### 问题现象
安装集群外客户端或使用集群外客户端时，有时会出现连接Spark任务端口失败的问题。
异常信息：Failed to bind SparkUi
```
Cannot assign requested address: Service ‘sparkDriver’ failed after 16 retries (on a random free port)! Consider explicitly setting the appropriate binding address for the service ‘sparkDriver’ (for example spark.driver.bindAddress for SparkDriver) to the correct binding address.
```
![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000001678353070.png "点击放大")
#### 处理步骤
应用无法访问到SparkUI的IP:PORT。可能有以下原因：
- **可能原因一** ：集群节点与客户端节点网络不通。
  **解决方法**：
  查看客户端节点"/etc/hosts"文件中是否配置集群节点映射，在客户端节点执行命令：
  **ping** *sparkui的IP*
  如果ping不通，检查映射配置与网络设置。
  
- **可能原因二** ：客户端节点防火墙未关闭。
  **解决方法**：
  执行如下命令可查看是否关闭：
  **systemctl status firewalld**（不同的操作系统查询命令不一致，此命令以CentOS为例）
  如下图所示：dead表示关闭。
  ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002047494805.png "点击放大")
  防火墙开则影响通信，执行如下命令关闭防火墙：
  **service firewalld stop**（不同的操作系统查询命令不一致，此命令以CentOS为例）
  

- **可能原因** **三** ：端口被占用，每一个Spark任务都会占用一个SparkUI端口，默认为22600，如果被占用则依次递增端口重试。但是有个默认重试次数，为16次。16次重试都失败后，会放弃该任务的运行。
  查看端口是否被占用：
  **ssh -v -p port username@ip**
  如果输出"Connection established"，则表示连接成功，端口已被占用。
  ![](https://support.huaweicloud.com/trouble-mrs/zh-cn_image_0000002047613841.png "点击放大")
  Spark UI端口范围由配置文件spark-defaults.conf中的参数"spark.random.port.min"和"spark.random.port.max"决定，如果该范围端口都已被占用，则
  导致无端口可用从而连接失败。
  **解决方法**：调节重连次数spark.port.maxRetries=50，并且调节executor随机端口范围spark.random.port.max+100
  
- **可能原因四** ：客户端Spark配置参数错误。
  **解决方法**：
  在客户端节点执行命令**cat spark-env.sh**，查看SPARK_LOCAL_HOSTNAME，是否为本机IP。
  该问题容易出现在从其他节点直接复制客户端时，配置参数未修改。
  需修改SPARK_LOCAL_HOSTNAME为本机IP。
  **注：如果集群使用EIP通信，则需要设置** **以下参数。**
  1. spark-default.conf中添加spark.driver.host =*EIP（客户端节点弹性公网IP）*
  
  2. spark-default.conf中添加spark.driver.bindAddress=*本地IP*
  
  3. spark-env.sh中修改SPARK_LOCAL_HOSTNAME=*EIP（客户端节点弹性公网IP）*
   
- **可能原因五** ：代码问题。
  **解决方法**：
  Spark在启动任务时会在客户端创建sparkDriverEnv并绑定DRIVER_BIND_ADDRESS，该逻辑并没有走到服务端，所以该问题产生的原因也是客户端节点操作系统环境问题导致sparkDriver获取不到对应的主机IP。
  可以尝试设置**spark.driver.bindAddress=127.0.0.1**，使提交任务driver端可以加载到loopbackAddress，从而规避问题。
  
 
