一、概述

前两天在调研kafka权限这一块,根据网上的一些资料通过命令窗口也能实现用户的创建啊、权限的查看、赋予、删除等。。
	但是关于java整合kafka权限这一块的资料少之又少,所以通过这些天的学习决定把自己整理的资料分享给大家。

二、kafka添加鉴权启动

这里没有做zookeeper的验证,因为懒。
	所以这里正常启动zookeeper,通过admin用户启动kafka,在这里不出kafka权限配置的教程,因为如果连这步也走不到,下面就别看了。

三、添加用户曲线救国

相信这里一大部分人没有查到java如何动态添加用户。
	其实这个规则是存在zookeeper上的所以kafka并没有提供Api,所以我又查阅资料发现可以通过java代码来调用linux脚本来实现这个操作。
  1. 在linux服务器上添加脚本
#!/bin/bash
SERVER=$1
USER=$2
PASSWORD=$3

if [ "x$SERVER" = "x" ] || [ "x$USER" = "x" ] || [ "x$PASSWORD" = "x" ]; then
    echo "usage: $0 <server:port> <user> <password>"
    exit
fi
/opt/software/kafka_2.11-2.2.1/bin/kafka-configs.sh --zookeeper $SERVER --alter --add-config "SCRAM-SHA-256=[iterations=8192,password=$PASSWORD],SCRAM-SHA-512=[password=$PASSWORD]" --entity-type users --entity-name $USER
  1. 参数说明(这不就可以通过前端页面传值了吗,)

参数

说明

zookeepers

zookeeper服务器ip:端口

username

用户名

password

密码

  1. java代码
    这段代码要和你的脚本放在一台服务器上哈,因为要读取你的脚本
/**
     * 创建用户
     * 可以传递参数 用户名 密码
     */
    @Test
    public void createUser() throws IOException {
        // broker地址
        String zookeepers = "192.168.10.23:2181";
        // 用户名
        String username = "amao";
        // 密码
        String password = "amao";
		
		
		// 这里是脚本地址2
        ProcessBuilder pb = new ProcessBuilder("bin/create-acl-kafka-user.sh", zookeepers , username, password);
        // 这里是jdk的配置,找到jdk的配置粘过来就行了
        pb.environment().put("PATH", "/usr/local/java/jdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin");
        // 这里也是脚本地址2  (代码运行之后 就是  脚本地址2+脚本地址1 = 脚本地址)
        ProcessBuilder directory = pb.redirectErrorStream(true)
                .directory(new File("/opt/software/kafka_2.11-2.2.1"));
        directory.start();
    }

四、给用户赋予权限

以下参数均可作为传参,实例代码中直接写死

参数

说明

bootstrapServers

kafa服务器ip+端口

user

要获取权限的用户名

aclOperation

权限(读、写…)

topic

权限作用于此队列

groupName

消费者组,消费者需要此参数

不多bb,直接上java代码
/**
     * 分配权限
     * 可以传递参数 服务器地址、用户名、权限类型、队列名、消费者组名
     */
    @Test
    public void competence() throws Exception {
        // kafka服务器ip+端口,多个可用逗号隔开
        private String bootstrapServers="192.168.10.23:9092";
        // 用户名
        private String user="cxy";
        // 权限
        private AclOperation aclOperation=AclOperation.READ;
        // 队列名
        private String topic = "test1";
        // 消费者组名
        private String groupName = "testConsumer"; 
        
        Map<String, Object> configs = new HashMap<>();
        // broker地址,多个用逗号分割
        configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        // 加密信息设置
        configs.put("security.protocol", "SASL_PLAINTEXT");
        configs.put("sasl.mechanism", "SCRAM-SHA-512");
        // 登录broker的账户 admin是管理员
        configs.put("sasl.jaas.config",
                "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"admin\" password=\"admin\";");
        KafkaAdmin admin = new KafkaAdmin(configs);

        AdminClient adminClient = null;
        try {
            adminClient = AdminClient.create(admin.getConfig());
            // principal:User:test2是需要赋予权限的帐号
            // host:主机 (*号即可)
            // operation:权限操作
            // permissionType:权限类型
            AccessControlEntry ace = new AccessControlEntry("User:"+user, "*", aclOperation, AclPermissionType.ALLOW);
            // resourceType:资源类型(topic)
            // name:topic名称
            // patternType:资源模式类型
            ResourcePattern topic = new ResourcePattern(ResourceType.TOPIC, topic, PatternType.LITERAL);
            ResourcePattern group = new ResourcePattern(ResourceType.GROUP, groupName, PatternType.LITERAL);
			// 给队列权限
            AclBinding topicAcl = new AclBinding(topic, ace);
            // 给消费者组权限,生产者去掉就行了
            AclBinding groupAcl = new AclBinding(group, ace);

            ArrayList<AclBinding> ab = new ArrayList<>();
            ab.add(topicAcl);
            ab.add(groupAcl);
            // 多个权限赋予可以传list
            adminClient.createAcls(ab);
        } catch (Exception e) {
            throw new Exception(e);
        } finally {
            if (ObjectUtil.isNotNull(adminClient)) {
                adminClient.close();
            }
        }
    }

五、重置offset

参数

说明

bootstrapServers

kafa服务器ip+端口

topic

队列

groupName

消费者组

offset

偏移量

partitionInfo

分区

/**
     * 重置offset前,消息监听方需要暂停服务
     * 可以传递参数 服务器地址、队列名、偏移量、消费者组、分区
     */
    @Test
    public void resetOffset() {
         // kafka服务器ip+端口,多个可用逗号隔开
        private String bootstrapServers="192.168.10.23:9092";
        // 队列名
        private String topic = "test1";
        // 消费者组名
        private String groupName = "testConsumer"; 
        // 偏移量
        private long offset = 1500L;
        // 分片
        private short partitionInfo = 1;
        
        
        Properties props = new Properties();
        // 服务器ip:端口号,集群用逗号分隔
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        // 消费者指定组,名称可以随意,注意相同消费组中的消费者只能对同一个分区消费一次
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupName);
        // 是否启用自动提交,默认true
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
        //重启时未消费得数据不再进行消费
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
        // key反序列化指定类
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        // value反序列化指定类,注意生产者与消费者要保持一致,否则解析出问题
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 1);
        props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, 30000);
        // 加密信息设置
        props.put("security.protocol", "SASL_PLAINTEXT");
        props.put("sasl.mechanism", "SCRAM-SHA-512");
        props.put("sasl.jaas.config",
                "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"admin\" password=\"admin\";");
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        // 所有分区都改
        // List<PartitionInfo> aa = consumer.partitionsFor(topic);
        // Map map = new HashMap();
        // for (int i = 0; i < aa.size(); i++) {
        //   map.put(new TopicPartition(topic, partitionInfo), new OffsetAndMetadata(offset));
        // }
        map.put(new TopicPartition(topic, partitionInfo), new OffsetAndMetadata(offset));
        consumer.commitSync(map);
        System.out.println("设置完成~~~~~~" + aa.size());
    }

创作不易大家记得点赞啊!!