Java static方法块只获取一次对象句柄供全局使用

前言

说实话,以前没碰见过必须只获取一次对象供全局使用的地方,或者说多重复实例化获得新的句柄对程序也没什么影响,但是这种习惯是非常很不好的,比如我最近在向hdfs写入文件的时候我希望FileSystem fs这个句柄只获得一次,后面所有的fs操作都用这一个对象就行,因为有kerberos的验证,如果每次操作都需要获取FileSystem fs这个句柄一来浪费验证的时间,二来会多占用一点内存!

代码

package com.bodyproperty.util;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.security.UserGroupInformation;
import org.springframework.stereotype.Component;
import java.io.IOException;

/**
 * @Auther: kc
 * @Date: 2018/12/19 11:22
 * @Description:
 */
@Component
public class HdfsUtil {
            static FileSystem fs;
            static{
            if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
                // Windows系统
                System.setProperty("java.security.krb5.conf", "C:/Program Files/MIT/Kerberos/krb5.ini");
            } else {
                // linux系统
                System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
            }
            Configuration conf = new Configuration();
            //这里设置namenode新
            conf.set("fs.defaultFS", "hdfs://test-da-shanghai:8020");
            //需要增加hadoop开启了安全的配置
            conf.setBoolean("hadoop.security.authorization", true);
            //配置安全认证方式为kerberos
            conf.set("hadoop.security.authentication", "kerberos");
            //设置namenode的principal
            conf.set("dfs.namenode.kerberos.principal", "nn/[email protected]");
            //设置datanode的principal值为“hdfs/[email protected]”
            conf.set("dfs.datanode.kerberos.principal", "dn/[email protected]");

            conf.set("dfs.support.append", "true");
            conf.set("dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER");
            conf.set("dfs.client.block.write.replace-datanode-on-failure.enable", "true");

            //通过hadoop security下中的 UserGroupInformation类来实现使用keytab文件登录
            UserGroupInformation.setConfiguration(conf);
            //设置登录的kerberos principal和对应的keytab文件,其中keytab文件需要kdc管理员生成给到开发人员
            try {
                UserGroupInformation.loginUserFromKeytab("[email protected]", "file:/usr/lihong/lihong.keytab");
            } catch (Exception e) {
                System.out.println("身份认证异常: " + e.getMessage());
                e.printStackTrace();
            }
                try {
                    fs = FileSystem.get(conf);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    public static  FileSystem getFs() {
                return  fs;
    }

}

其实整个代码中间的验证全部不用看,主要就是我用static代码块将验证的逻辑包围起来,然后fs这个对象就只会生成一次了,每次调用getFs()方法获得的都是同一个fs对象 。

发布了169 篇原创文章 · 获赞 224 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/sureSand/article/details/85244059
今日推荐