Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >实战:彻底搞定 SpringBoot 整合 Kafka(spring-kafka深入探秘)

实战:彻底搞定 SpringBoot 整合 Kafka(spring-kafka深入探秘)

作者头像
Java团长
发布于 2019-11-21 10:09:40
发布于 2019-11-21 10:09:40
51.5K07
代码可运行
举报
运行总次数:7
代码可运行

来源:my.oschina.net/keking/blog/3056698


前言

kafka是一个消息队列产品,基于Topic partitions的设计,能达到非常高的消息发送处理性能。Spring创建了一个项目Spring-kafka,封装了Apache 的Kafka-client,用于在Spring项目里快速集成kafka。

除了简单的收发消息外,Spring-kafka还提供了很多高级功能,下面我们就来一一探秘这些用法。

项目地址:https://github.com/spring-projects/spring-kafka


简单集成

引入依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
  <groupId>org.springframework.kafka</groupId>
  <artifactId>spring-kafka</artifactId>
  <version>2.2.6.RELEASE</version>
</dependency>

添加配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.kafka.producer.bootstrap-servers=127.0.0.1:9092

测试发送和接收

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: kl @kailing.pub
 * @date: 2019/5/30
 */
@SpringBootApplication
@RestController
public class Application {

    private final Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    private KafkaTemplate<Object, Object> template;

    @GetMapping("/send/{input}")
    public void sendFoo(@PathVariable String input) {
        this.template.send("topic_input", input);
    }
    @KafkaListener(id = "webGroup", topics = "topic_input")
    public void listen(String input) {
        logger.info("input value: {}" , input);
    }
}

启动应用后,在浏览器中输入:http://localhost:8080/send/kl。就可以在控制台看到有日志输出了:input value: "kl"。基础的使用就这么简单。发送消息时注入一个KafkaTemplate,接收消息时添加一个@KafkaListener注解即可。


Spring-kafka-test嵌入式Kafka Server

不过上面的代码能够启动成功,前提是你已经有了Kafka Server的服务环境,我们知道Kafka是由Scala + Zookeeper构建的,可以从官网下载部署包在本地部署。

但是,我想告诉你,为了简化开发环节验证Kafka相关功能,Spring-Kafka-Test已经封装了Kafka-test提供了注解式的一键开启Kafka Server的功能,使用起来也是超级简单。本文后面的所有测试用例的Kafka都是使用这种嵌入式服务提供的。

引入依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
   <groupId>org.springframework.kafka</groupId>
   <artifactId>spring-kafka-test</artifactId>
   <version>2.2.6.RELEASE</version>
   <scope>test</scope>
</dependency>

启动服务

下面使用Junit测试用例,直接启动一个Kafka Server服务,包含四个Broker节点。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationTests.class)
@EmbeddedKafka(count = 4,ports = {9092,9093,9094,9095})
public class ApplicationTests {
    @Test
    public void contextLoads()throws IOException {
        System.in.read();
    }
}

如上:只需要一个注解@EmbeddedKafka即可,就可以启动一个功能完整的Kafka服务,是不是很酷。默认只写注解不加参数的情况下,是创建一个随机端口的Broker,在启动的日志中会输出具体的端口以及默认的一些配置项。

不过这些我们在Kafka安装包配置文件中的配置项,在注解参数中都可以配置,下面详解下@EmbeddedKafka注解中的可设置参数 :

  • value:broker节点数量
  • count:同value作用一样,也是配置的broker的节点数量
  • controlledShutdown:控制关闭开关,主要用来在Broker意外关闭时减少此Broker上Partition的不可用时间

Kafka是多Broker架构的高可用服务,一个Topic对应多个partition,一个Partition可以有多个副本Replication,这些Replication副本保存在多个Broker,用于高可用。

但是,虽然存在多个分区副本集,当前工作副本集却只有一个,默认就是首次分配的副本集【首选副本】为Leader,负责写入和读取数据。当我们升级Broker或者更新Broker配置时需要重启服务,这个时候需要将partition转移到可用的Broker。

下面涉及到三种情况

1、直接关闭Broker:当Broker关闭时,Broker集群会重新进行选主操作,选出一个新的Broker来作为Partition Leader,选举时此Broker上的Partition会短时不可用

2、开启controlledShutdown:当Broker关闭时,Broker本身会先尝试将Leader角色转移到其他可用的Broker上

3、使用命令行工具使用bin/kafka-preferred-replica-election.sh,手动触发PartitionLeader角色转移

ports:端口列表,是一个数组。对应了count参数,有几个Broker,就要对应几个端口号

brokerProperties:Broker参数设置,是一个数组结构,支持如下方式进行Broker参数设置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@EmbeddedKafka(brokerProperties = {"log.index.interval.bytes = 4096","num.io.threads = 8"})

okerPropertiesLocation:Broker参数文件设置

功能同上面的brokerProperties,只是Kafka Broker的可设置参数达182个之多,都像上面这样配置肯定不是最优方案,所以提供了加载本地配置文件的功能,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@EmbeddedKafka(brokerPropertiesLocation = "classpath:application.properties")

创建新的Topic

默认情况下,如果在使用KafkaTemplate发送消息时,Topic不存在,会创建一个新的Topic,默认的分区数和副本数为如下Broker参数来设定

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
num.partitions = 1 #默认Topic分区数
num.replica.fetchers = 1 #默认副本数

程序启动时创建Topic

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: kl @kailing.pub
 * @date: 2019/5/31
 */
@Configuration
public class KafkaConfig {
    @Bean
    public KafkaAdmin admin(KafkaProperties properties){
        KafkaAdmin admin = new KafkaAdmin(properties.buildAdminProperties());
        admin.setFatalIfBrokerNotAvailable(true);
        return admin;
    }
    @Bean
    public NewTopic topic2() {
        return new NewTopic("topic-kl", 1, (short) 1);
    }
}

如果Kafka Broker支持(1.0.0或更高版本),则如果发现现有Topic的Partition 数少于设置的Partition 数,则会新增新的Partition分区。

关于KafkaAdmin有几个常用的用法如下:

setFatalIfBrokerNotAvailable(true):默认这个值是False的,在Broker不可用时,不影响Spring 上下文的初始化。如果你觉得Broker不可用影响正常业务需要显示的将这个值设置为True

setAutoCreate(false) : 默认值为True,也就是Kafka实例化后会自动创建已经实例化的NewTopic对象

initialize():当setAutoCreate为false时,需要我们程序显示的调用admin的initialize()方法来初始化NewTopic对象

代码逻辑中创建

有时候我们在程序启动时并不知道某个Topic需要多少Partition数合适,但是又不能一股脑的直接使用Broker的默认设置,这个时候就需要使用Kafka-Client自带的AdminClient来进行处理。

上面的Spring封装的KafkaAdmin也是使用的AdminClient来处理的。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Autowired
    private KafkaProperties properties;
    @Test
    public void testCreateToipc(){
        AdminClient client = AdminClient.create(properties.buildAdminProperties());
        if(client !=null){
            try {
                Collection<NewTopic> newTopics = new ArrayList<>(1);
                newTopics.add(new NewTopic("topic-kl",1,(short) 1));
                client.createTopics(newTopics);
            }catch (Throwable e){
                e.printStackTrace();
            }finally {
                client.close();
            }
        }
    }

ps:其他的方式创建Topic

上面的这些创建Topic方式前提是你的spring boot版本到2.x以上了,因为spring-kafka2.x版本只支持spring boot2.x的版本。在1.x的版本中还没有这些api。下面补充一种在程序中通过Kafka_2.10创建Topic的方式

引入依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
       <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka_2.10</artifactId>
            <version>0.8.2.2</version>
        </dependency>

api方式创建

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testCreateTopic()throws Exception{
        ZkClient zkClient =new ZkClient("127.0.0.1:2181", 3000, 3000, ZKStringSerializer$.MODULE$)
        String topicName = "topic-kl";
        int partitions = 1;
        int replication = 1;
        AdminUtils.createTopic(zkClient,topicName,partitions,replication,new Properties());
    }

注意下ZkClient最后一个构造入参,是一个序列化反序列化的接口实现,博主测试如果不填的话,创建的Topic在ZK上的数据是有问题的,默认的Kafka实现也很简单,就是做了字符串UTF-8编码处理。

ZKStringSerializer$是Kafka中已经实现好的一个接口实例,是一个Scala的伴生对象,在Java中直接调用点MODULE$就可以得到一个实例

命令方式创建

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testCreateTopic(){
        String [] options= new String[]{
                "--create",
                "--zookeeper","127.0.0.1:2181",
                "--replication-factor", "3",
                "--partitions", "3",
                "--topic", "topic-kl"
        };
        TopicCommand.main(options);
    }

消息发送之KafkaTemplate探秘

获取发送结果

异步获取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        template.send("","").addCallback(new ListenableFutureCallback<SendResult<Object, Object>>() {
            @Override
            public void onFailure(Throwable throwable) {
                ......
            }

            @Override
            public void onSuccess(SendResult<Object, Object> objectObjectSendResult) {
                ....
            }
        });

同步获取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        ListenableFuture<SendResult<Object,Object>> future = template.send("topic-kl","kl");
        try {
            SendResult<Object,Object> result = future.get();
        }catch (Throwable e){
            e.printStackTrace();
        }

kafka事务消息

默认情况下,Spring-kafka自动生成的KafkaTemplate实例,是不具有事务消息发送能力的。需要使用如下配置激活事务特性。事务激活后,所有的消息发送只能在发生事务的方法内执行了,不然就会抛一个没有事务交易的异常

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.kafka.producer.transaction-id-prefix=kafka_tx.

当发送消息有事务要求时,比如,当所有消息发送成功才算成功,如下面的例子:假设第一条消费发送后,在发第二条消息前出现了异常,那么第一条已经发送的消息也会回滚。

而且正常情况下,假设在消息一发送后休眠一段时间,在发送第二条消息,消费端也只有在事务方法执行完成后才会接收到消息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @GetMapping("/send/{input}")
    public void sendFoo(@PathVariable String input) {
        template.executeInTransaction(t ->{
            t.send("topic_input","kl");
            if("error".equals(input)){
                throw new RuntimeException("failed");
            }
            t.send("topic_input","ckl");
            return true;
        });
    }

当事务特性激活时,同样,在方法上面加@Transactional注解也会生效

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @GetMapping("/send/{input}")
    @Transactional(rollbackFor = RuntimeException.class)
    public void sendFoo(@PathVariable String input) {
        template.send("topic_input", "kl");
        if ("error".equals(input)) {
            throw new RuntimeException("failed");
        }
        template.send("topic_input", "ckl");
    }

Spring-Kafka的事务消息是基于Kafka提供的事务消息功能的。而Kafka Broker默认的配置针对的三个或以上Broker高可用服务而设置的。这边在测试的时候为了简单方便,使用了嵌入式服务新建了一个单Broker的Kafka服务,出现了一些问题:如

1、事务日志副本集大于Broker数量,会抛如下异常:

Number of alive brokers '1' does not meet the required replication factor '3' for the transactions state topic (configured via 'transaction.state.log.replication.factor'). This error can be ignored if the cluster is starting up and not all brokers are up yet.

默认Broker的配置transaction.state.log.replication.factor=3,单节点只能调整为1

2、副本数小于副本同步队列数目,会抛如下异常

Number of insync replicas for partition __transaction_state-13 is [1], below required minimum [2]

默认Broker的配置transaction.state.log.min.isr=2,单节点只能调整为1

ReplyingKafkaTemplate获得消息回复

ReplyingKafkaTemplate是KafkaTemplate的一个子类,除了继承父类的方法,新增了一个方法sendAndReceive,实现了消息发送\回复语义

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RequestReplyFuture<K, V, R> sendAndReceive(ProducerRecord<K, V> record);

也就是我发送一条消息,能够拿到消费者给我返回的结果。就像传统的RPC交互那样。当消息的发送者需要知道消息消费者的具体的消费情况,非常适合这个api。

如,一条消息中发送一批数据,需要知道消费者成功处理了哪些数据。下面代码演示了怎么集成以及使用ReplyingKafkaTemplate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: kl @kailing.pub
 * @date: 2019/5/30
 */
@SpringBootApplication
@RestController
public class Application {
    private final Logger logger = LoggerFactory.getLogger(Application.class);
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @Bean
    public ConcurrentMessageListenerContainer<String, String> repliesContainer(ConcurrentKafkaListenerContainerFactory<String, String> containerFactory) {
        ConcurrentMessageListenerContainer<String, String> repliesContainer = containerFactory.createContainer("replies");
        repliesContainer.getContainerProperties().setGroupId("repliesGroup");
        repliesContainer.setAutoStartup(false);
        return repliesContainer;
    }

    @Bean
    public ReplyingKafkaTemplate<String, String, String> replyingTemplate(ProducerFactory<String, String> pf, ConcurrentMessageListenerContainer<String, String> repliesContainer) {
        return new ReplyingKafkaTemplate(pf, repliesContainer);
    }

    @Bean
    public KafkaTemplate kafkaTemplate(ProducerFactory<String, String> pf) {
        return new KafkaTemplate(pf);
    }

    @Autowired
    private ReplyingKafkaTemplate template;

    @GetMapping("/send/{input}")
    @Transactional(rollbackFor = RuntimeException.class)
    public void sendFoo(@PathVariable String input) throws Exception {
        ProducerRecord<String, String> record = new ProducerRecord<>("topic-kl", input);
        RequestReplyFuture<String, String, String> replyFuture = template.sendAndReceive(record);
        ConsumerRecord<String, String> consumerRecord = replyFuture.get();
        System.err.println("Return value: " + consumerRecord.value());
    }

    @KafkaListener(id = "webGroup", topics = "topic-kl")
    @SendTo
    public String listen(String input) {
        logger.info("input value: {}", input);
        return "successful";
    }
}

Spring-kafka消息消费用法探秘

@KafkaListener的使用

前面在简单集成中已经演示过了@KafkaListener接收消息的能力,但是@KafkaListener的功能不止如此,其他的比较常见的,使用场景比较多的功能点如下:

  • 显示的指定消费哪些Topic和分区的消息,
  • 设置每个Topic以及分区初始化的偏移量,
  • 设置消费线程并发度
  • 设置消息异常处理器
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @KafkaListener(id = "webGroup", topicPartitions = {
            @TopicPartition(topic = "topic1", partitions = {"0", "1"}),
                    @TopicPartition(topic = "topic2", partitions = "0",
                            partitionOffsets = @PartitionOffset(partition = "1", initialOffset = "100"))
            },concurrency = "6",errorHandler = "myErrorHandler")
    public String listen(String input) {
        logger.info("input value: {}", input);
        return "successful";
    }

其他的注解参数都很好理解,errorHandler需要说明下,设置这个参数需要实现一个接口KafkaListenerErrorHandler。而且注解里的配置,是你自定义实现实例在spring上下文中的Name。比如,上面配置为errorHandler = "myErrorHandler"。则在spring上线中应该存在这样一个实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: kl @kailing.pub
 * @date: 2019/5/31
 */
@Service("myErrorHandler")
public class MyKafkaListenerErrorHandler implements KafkaListenerErrorHandler {
    Logger logger =LoggerFactory.getLogger(getClass());
    @Override
    public Object handleError(Message<?> message, ListenerExecutionFailedException exception) {
        logger.info(message.getPayload().toString());
        return null;
    }
    @Override
    public Object handleError(Message<?> message, ListenerExecutionFailedException exception, Consumer<?, ?> consumer) {
        logger.info(message.getPayload().toString());
        return null;
    }
}

手动Ack模式

手动ACK模式,由业务逻辑控制提交偏移量。比如程序在消费时,有这种语义,特别异常情况下不确认ack,也就是不提交偏移量,那么你只能使用手动Ack模式来做了。开启手动首先需要关闭自动提交,然后设置下consumer的消费模式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.listener.ack-mode=manual

上面的设置好后,在消费时,只需要在@KafkaListener监听方法的入参加入Acknowledgment 即可,执行到ack.acknowledge()代表提交了偏移量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @KafkaListener(id = "webGroup", topics = "topic-kl")
    public String listen(String input, Acknowledgment ack) {
        logger.info("input value: {}", input);
        if ("kl".equals(input)) {
            ack.acknowledge();
        }
        return "successful";
    }

@KafkaListener注解监听器生命周期

@KafkaListener注解的监听器的生命周期是可以控制的,默认情况下,@KafkaListener的参数autoStartup = "true"。也就是自动启动消费,但是也可以同过KafkaListenerEndpointRegistry来干预他的生命周期。

KafkaListenerEndpointRegistry有三个动作方法分别如:start(),pause(),resume()/启动,停止,继续。如下代码详细演示了这种功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: kl @kailing.pub
 * @date: 2019/5/30
 */
@SpringBootApplication
@RestController
public class Application {
    private final Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    private KafkaTemplate template;

    @GetMapping("/send/{input}")
    @Transactional(rollbackFor = RuntimeException.class)
    public void sendFoo(@PathVariable String input) throws Exception {
        ProducerRecord<String, String> record = new ProducerRecord<>("topic-kl", input);
        template.send(record);
    }

    @Autowired
    private KafkaListenerEndpointRegistry registry;

    @GetMapping("/stop/{listenerID}")
    public void stop(@PathVariable String listenerID){
        registry.getListenerContainer(listenerID).pause();
    }
    @GetMapping("/resume/{listenerID}")
    public void resume(@PathVariable String listenerID){
        registry.getListenerContainer(listenerID).resume();
    }
    @GetMapping("/start/{listenerID}")
    public void start(@PathVariable String listenerID){
        registry.getListenerContainer(listenerID).start();
    }
    @KafkaListener(id = "webGroup", topics = "topic-kl",autoStartup = "false")
    public String listen(String input) {
        logger.info("input value: {}", input);
        return "successful";
    }
}

在上面的代码中,listenerID就是@KafkaListener中的id值“webGroup”。项目启动好后,分别执行如下url,就可以看到效果了。

先发送一条消息:http://localhost:8081/send/ckl。因为autoStartup = "false",所以并不会看到有消息进入监听器。

接着启动监听器:http://localhost:8081/start/webGroup。可以看到有一条消息进来了。

暂停和继续消费的效果使用类似方法就可以测试出来了。

SendTo消息转发

前面的消息发送响应应用里面已经见过@SendTo,其实除了做发送响应语义外,@SendTo注解还可以带一个参数,指定转发的Topic队列。

常见的场景如,一个消息需要做多重加工,不同的加工耗费的cup等资源不一致,那么就可以通过跨不同Topic和部署在不同主机上的consumer来解决了。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @KafkaListener(id = "webGroup", topics = "topic-kl")
    @SendTo("topic-ckl")
    public String listen(String input) {
        logger.info("input value: {}", input);
        return input + "hello!";
    }

    @KafkaListener(id = "webGroup1", topics = "topic-ckl")
    public void listen2(String input) {
        logger.info("input value: {}", input);
    }

消息重试和死信队列的应用

除了上面谈到的通过手动Ack模式来控制消息偏移量外,其实Spring-kafka内部还封装了可重试消费消息的语义,也就是可以设置为当消费数据出现异常时,重试这个消息。而且可以设置重试达到多少次后,让消息进入预定好的Topic。也就是死信队列里。

下面代码演示了这种效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Autowired
    private KafkaTemplate template;

    @Bean
    public ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory(
            ConcurrentKafkaListenerContainerFactoryConfigurer configurer,
            ConsumerFactory<Object, Object> kafkaConsumerFactory,
            KafkaTemplate<Object, Object> template) {
        ConcurrentKafkaListenerContainerFactory<Object, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
        configurer.configure(factory, kafkaConsumerFactory);
        //最大重试三次
        factory.setErrorHandler(new SeekToCurrentErrorHandler(new DeadLetterPublishingRecoverer(template), 3));
        return factory;
    }

    @GetMapping("/send/{input}")
    public void sendFoo(@PathVariable String input) {
        template.send("topic-kl", input);
    }

    @KafkaListener(id = "webGroup", topics = "topic-kl")
    public String listen(String input) {
        logger.info("input value: {}", input);
        throw new RuntimeException("dlt");
    }

    @KafkaListener(id = "dltGroup", topics = "topic-kl.DLT")
    public void dltListen(String input) {
        logger.info("Received from DLT: " + input);
    }

上面应用,在topic-kl监听到消息会,会触发运行时异常,然后监听器会尝试三次调用,当到达最大的重试次数后。消息就会被丢掉重试死信队列里面去。死信队列的Topic的规则是,业务Topic名字+“.DLT”。

如上面业务Topic的name为“topic-kl”,那么对应的死信队列的Topic就是“topic-kl.DLT”


文末结语

最近业务上使用了kafka用到了Spring-kafka,所以系统性的探索了下Spring-kafka的各种用法,发现了很多好玩很酷的特性,比如,一个注解开启嵌入式的Kafka服务、像RPC调用一样的发送\响应语义调用、事务消息等功能。

希望此博文能够帮助那些正在使用Spring-kafka或即将使用的人少走一些弯路少踩一点坑。

扫描上方二维码获取更多Java干货

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java团长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
后端技术杂谈5:云计算的前世今生
长期专注于kubernetes, OpenStack、Hadoop、Docker、Lucene、Mesos等开源软件的企业级应用及产品化。曾出版《Lucene应用开发揭秘》。
Java技术江湖
2019/12/09
8530
后端技术杂谈5:云计算的前世今生
Kubernetes系列学习文章 - 什么是容器云?(一)
| 导语 前面我们学习了docker的一些知识,那么从今天起,我们开始学习下Kubernetes(k8s)方面系列知识。大家有兴趣可以跟我一起学习。另外,本人才疏学浅,难免有发现不了的点和层面,望大家多指正。
宝哥@上云专家
2019/05/04
8.2K0
Kubernetes系列学习文章 - 什么是容器云?(一)
下一代云计算?容器云和微服务时代的来临
在搜索引擎里输入下一代云计算[注],给出的结果多是CaaS和Docker。CaaS在国内被包装成了云服务的新名词,意为容器即服务。而Docker 这一从2013年开始席卷云计算领域的新技术,已不仅仅是一个开源的应用容器引擎,商业化方面的成功也让其成为云计算行业名副其实的神话。 “传统云计算不能解决的问题,需要新平台来解决。”网易蜂巢的产品负责人陈谔在同媒体进行交流分享时,说出了这样一个观点。而他眼中的新平台正是红极一时的Docker容器和深受架构师与技术决策者关注的微服务架构。 传统云计算在实际应用时遇到了
静一
2018/03/26
1.6K0
Docker崛起,云计算巨头们如何对待这个“坏孩子”
不久前,Docker官方公布的数据显示,全球已有46万个应用Docker 化,并且实现两年增长3000%。以Docker为代表的容器技术在发展速度上,业已超过了曾经的虚拟化技术和云计算技术。 或许也正因如此,2015年被称为Docker野蛮扩张的一年,先后通过了OCI和CNCF 两大标准组织的确立,更是在中国引发了如火如荼的Docker 创业之风,出现了阿里百川、网易蜂巢等大批基于Docker的容器云。诞生于2013年的Docker技术,让那些成熟的云计算服务突然显得老迈、迟缓且落伍,而国内外的云计算巨
静一
2018/03/26
1.4K0
Docker崛起,云计算巨头们如何对待这个“坏孩子”
Docker系列学习文章 - 什么是docker?(二)
| 导语 前面我们介绍了什么是容器,那么这篇文章我们继续跟大家讲解什么是docker。 docker是目前最火的LXC高级容器引擎,docker到现在几乎是容器的代名词了,所以学习容器从docker入手是非常正确的!
宝哥@上云专家
2018/05/07
3K10
Docker系列学习文章 - 什么是docker?(二)
入门级容器技术解析:Docker和K8s的区别与关系
1.了解容器的由来,以及容器的概念。 2.了解Docker是什么及其作用。 3.了解K8s是什么及其作用。
Rossy Yan
2024/12/24
4260
入门级容器技术解析:Docker和K8s的区别与关系
Docker是什么?
Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。
黑洞代码
2021/12/04
3660
Docker是什么?
Kubernetes VS Docker | 结局意想不到!
Kubernetes vs Docker是云计算行业中多次提到的话题。无论您是否有技术背景,需要快速介绍,还是需要做出业务决策,我希望以下几点将一次性澄清这一问题。
xcbeyond
2020/04/02
7380
Kubernetes 学习(十一)Kubernetes 基本知识点总结
0. 前言 最近一段时间校招,早期拿到了字节跳动、腾讯等公司的意向书 后面对面试有些懈怠,渐渐投入毕设中,疏于复习,感觉好多知识点开始遗忘,后来面试了美团等企业发现这个问题渐渐开始严重起来 是时候重新总结一下之前的知识点了,也为后续的面试和学习过程打打基础,持续更新和修改 参考文献:深入剖析 Kubernetes 1. 零散知识点 PaaS:Platform as a Service(平台即服务)是一种云计算产品,其中服务提供商向客户端提供平台,使他们能够开发、运行和管理业务应用程序,而无需构建和维护基础架
西凉风雷
2022/11/23
3930
Kubernetes 学习(十一)Kubernetes 基本知识点总结
Docker会是改变世界的那只“箱子”吗?
“很多时候,我们面临未来的预测和期望,其实很多答案已经存在在历史中。” 改变世界的“箱子” “没有集装箱,就不会有全球化。”,《经济学家》这个评论可以说是对于这个普通的箱子的历史性地位的一个总结。1956年4月26日,当集装箱之父麦克莱恩第一次将集装箱这种方式用于货物运输时,他肯定想像不到他的这个看似普通的发明,会对这个世界的影响如此深远。因为如果把全球经济比作一个高速运转的复杂的机器,那么以集装箱为核心的现代运输体系就是带动这台机器高速运转的齿轮和传送带。 这只普通的箱子,技术含量不高,也并不复杂。
腾讯大数据
2018/01/26
8610
Docker这么火,但是你真的了解吗?
在了解Docker之前,我们先了解一下集装箱这个概念。 集装箱是? 集装箱,英文名container.集装箱的出现,大大降低了货物运输的成本,实现了货物运输的标准化,以此为基础逐步建立全球范围内的船舶、港口、航线、公路、中转站、桥梁、隧道、多式联运相配套的物流系统,世界经济形态因此而改变。 集装箱最大的成功在于其产品的标准化以及由此建立的一整套运输体系。 英国《经济学人》杂志在一篇评论中,对集装箱运输这一现代物流模式的有这样的评价。 如果没有集装箱,就不会有全球化。
Rainbond开源
2018/05/31
1.2K0
一篇文章带你看懂云计算的前世今生
云计算在出现16年后,已经成为IT领域的标配模式。它易操作、存储量惊人、对用户来说几乎无处不在。它不仅成就了世界上最大的公司,同时也给小公司提供支持。云改变了服务供给双方的经济模式,同时带来更多新的机遇。
小云
2019/05/19
1.9K0
一篇文章带你看懂云计算的前世今生
图文并茂!带你深度解析Kubernetes
导语 | 在云原生技术发展的浪潮之中,Kubernetes作为容器编排领域的事实标准和云原生领域的关键项目,其诞生与完善有着对应的技术历史背景,了解这个过程,对于系统的理解Kubernetes的核心思想、架构设计、实现原理等会很有帮助。 在云原生技术发展的浪潮之中,Kubernetes伴随着容器技术的发展,成为了目前云时代的操作系统。Kubernetes作为容器编排领域的事实标准和云原生领域的关键项目,已经是云原生时代工程师最需要理解与实践的核心技术。 但技术的发展从来都不是一蹴而就,Kubernetes的
腾讯云开发者
2022/07/07
7900
图文并茂!带你深度解析Kubernetes
五分钟学后端技术:一篇文章告诉你什么是云计算!
早在十年前,市场上就出现了很多和云计算相关的岗位,当时正是云计算技术最火热的时代,不管是BAT还是华为等企业都开始布局云计算,于是OpenStack研发、容器研发、底层开发等相关岗位相应地也越来越多,虽然这几年大数据和AI的风头已经完全压过了云计算,但是这一门技术仍然在现如今的技术体系中占有很重要的位置。那么,到底什么是云计算,就是我们每一个要学习云计算技术的朋友要了解的事情了,根据百度百科的介绍
程序员黄小斜
2020/04/02
9590
云原生的发展路线中考虑过我的未来吗?
本文仅用于简单普及,达到的目的是给没接触过或者很少接触过这方面的人一点感觉,阅读起来会比较轻松,作者深知短篇幅文章是不可能真正教会什么的,所以也不会出现 RTFM(Read The Fucking Manual) 的内容。
公众号: 云原生生态圈
2022/02/16
4290
云原生的发展路线中考虑过我的未来吗?
[入门]容器
在上个世纪50年代前,当时物流远没有现代这么普及,集装箱在当时并不被认可,几乎所有货物都是通过零散方式运输。
木禾wen
2019/11/15
7740
[入门]容器
docker (一)
在写这个文章之前先说一件事,上次发的那篇文章要提一下。当时打码没有打好,可能会对站长造成了不好的影响。 因为有人踩着我的足迹进去了~我承认上一篇的做法有点娱乐圈,但是我真的想装X,我打码干嘛,直接挂黑页放出来不就得了。其实主要是思路,因为玩这个有时候这样子会比较有趣一点。没什么技术含量~也希望不要有人搞破坏,因为我拿到权限都是扔那边~基本都是好朋友木头在做下一步挖掘利用,我只想低调学习分享技术~我也懒得帮站长修复了,甚至好多漏洞我都懒得去向SRC提交…对我来说这种东西没意义,我有那么多时间我还不如去多学点东
lonelyvaf
2018/06/07
5570
关于云原生,这些你要知道
“新冠疫情从根本上改变了商业模式,工作流向在线迁移的速度比以往任何时候都要快。越来越多的公司和消费者依靠电子商务“ B2B”和B2C”,以及网上银行促进创新以满足日益增长的客户需求,云原生技术在其中发挥重要作用,同时也加速了云原生的普及。
Lydiasq
2023/03/06
4110
关于云原生,这些你要知道
Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry
大家在工作中或许或多或少都接触过Docker,那你知道Docker以及容器化背后的原理到底是什么吗?
葡萄城控件
2021/06/21
6750
Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry
虚拟化到Service Mesh演进过程
虚拟机由某些特定的硬件和内核虚拟化组成,运行客户操作系统。称为管理程序的软件创建虚拟化硬件,其可以包括虚拟磁盘,虚拟网络接口,虚拟 CPU 等。虚拟机还包括可以与此虚拟硬件通信的宾客内核。管理程序可以托管,这意味着它是一些在主机操作系统(MacOS)上运行的软件,如示例中所示。它也可以是裸机,直接在机器硬件上运行(替换你的操作系统)。无论哪种方式,管理程序方法都被认为是重量级的,因为它需要虚拟化多个部分(如果不是全部硬件和内核)。
架构狂人
2023/09/29
2050
虚拟化到Service Mesh演进过程
推荐阅读
相关推荐
后端技术杂谈5:云计算的前世今生
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验