Protobuf: 高效数据传输的秘密武器-速看料
当涉及到网络通信和数据存储时,数据序列化一直都是一个重要的话题;特别是现在很多公司都在推行微服务,数据序列化更是重中之重,通常会选择使用 JSON 作为数据交换格式,且 JSON 已经成为业界的主流。但是 Google 这么大的公司使用的却是一种被称为 Protobuf的数据交换格式,它是有什么优势吗?这篇文章介绍 Protobuf 的相关知识。
GitHub:https://github.com/protocolbuffers/protobuf
(资料图片)
官方文档:https://protobuf.dev/overview/
Protobuf 介绍Protobuf(Protocol Buffers)是由 Google 开发的一种轻量级、高效的数据交换格式,它被用于结构化数据的序列化、反序列化和传输。相比于 XML 和 JSON 等文本格式,Protobuf 具有更小的数据体积、更快的解析速度和更强的可扩展性。
Protobuf 的核心思想是使用协议(Protocol)来定义数据的结构和编码方式。使用 Protobuf,可以先定义数据的结构和各字段的类型、字段等信息,然后使用Protobuf提供的编译器生成对应的代码,用于序列化和反序列化数据。由于 Protobuf 是基于二进制编码的,因此可以在数据传输和存储中实现更高效的数据交换,同时也可以跨语言使用。
相比于 XML 和 JSON,Protobuf 有以下几个优势:
更小的数据量:Protobuf 的二进制编码通常比 XML 和 JSON 小 3-10 倍,因此在网络传输和存储数据时可以节省带宽和存储空间。
更快的序列化和反序列化速度:由于 Protobuf 使用二进制格式,所以序列化和反序列化速度比 XML 和 JSON 快得多。
跨语言:Protobuf 支持多种编程语言,可以使用不同的编程语言来编写客户端和服务端。这种跨语言的特性使得 Protobuf 受到很多开发者的欢迎(JSON 也是如此)。
易于维护可扩展:Protobuf 使用 .proto 文件定义数据模型和数据格式,这种文件比 XML 和 JSON 更容易阅读和维护,且可以在不破坏原有协议的基础上,轻松添加或删除字段,实现版本升级和兼容性。
编写 Protobuf使用 Protobuf 的语言定义文件(.proto)可以定义要传输的信息的数据结构,可以包括各个字段的名称、类型等信息。同时也可以相互嵌套组合,构造出更加复杂的消息结构。
比如想要构造一个地址簿 AddressBook 信息结构。一个 AddressBook 可以包含多个人员 Person 信息,每个 Person 信息可以包含 id、name、email 信息,同时一个 Person 也可以包含多个电话号码信息 PhoneNumber,每个电话号码信息需要指定号码种类,如手机、家庭电话、工作电话等。
如果使用 Protobuf 编写定义文件如下:
// 文件:addressbook.protosyntax = "proto3";// 指定 protobuf 包名,防止有相同类名的 message 定义package com.wdbyte.protobuf;// 是否生成多个文件option java_multiple_files = true;// 生成的文件存放在哪个包下option java_package = "com.wdbyte.tool.protos";// 生成的类名,如果没有指定,会根据文件名自动转驼峰来命名option java_outer_classname = "AddressBookProtos";message Person { // =1,=2 作为序列化后的二进制编码中的字段的唯一标签,也因此,1-15 比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。 optional int32 id = 1; optional string name = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { optional string number = 1; optional PhoneType type = 2; } repeated PhoneNumber phones = 4;}message AddressBook { repeated Person people = 1;}
Protobuf 文件中的语法解释。
头部全局定义syntax = "proto3";
指定 Protobuf 版本为版本3(最新版本)package com.wdbyte.protobuf;
指定 Protobuf 包名,防止有相同类名的 message
定义,这个包名是生成的类中所用到的一些信息的前缀,并非类所在包。option java_multiple_files = true;
是否生成多个文件。若 false
,则只会生成一个类,其他类以内部类形式提供。option java_package =
生成的类所在包。option java_outer_classname
生成的类名,若无,自动使用文件名进行驼峰转换来为类命名。消息结构具体定义message Person
定一个了一个 Person 类。
Person 类中的字段被 optional
修饰,被 optional
修饰说明字段可以不赋值。
optional
表示可选字段,可以不赋值。修饰符 repeated
表示数据重复多个,如数组,如 List。修饰符 required
表示必要字段,必须给值,否则会报错 RuntimeException
,但是在 Protobuf 版本 3 中被移除。即使在版本 2 中也应该慎用,因为一旦定义,很难更改。字段类型定义修饰符后面紧跟的是字段类型,如 int32
、string
。常用的类型如下:
int32、int64、uint32、uint64
:整数类型,包括有符号和无符号类型。
float、double
:浮点数类型。
bool
:布尔类型,只有两个值,true 和 false。
string
:字符串类型。
bytes
:二进制数据类型。
enum
:枚举类型,枚举值可以是整数或字符串。
message
:消息类型,可以嵌套其他消息类型,类似于结构体。
字段后面的 =1,=2
是作为序列化后的二进制编码中的字段的对应标签,因为 Protobuf 消息在序列化后是不包含字段信息的,只有对应的字段序号,所以节省了空间。也因此,1-15 比 16 会少一个字节,所以尽量使用 1-15 来指定常用字段。且一旦定义,不要随意更改,否则可能会对不上序列化信息。
使用 Protobuf 提供的编译器,可以将 .proto
文件编译成各种语言的代码文件(如 Java、C++、Python 等)。
下载编译器:https://github.com/protocolbuffers/protobuf/releases/latest
安装完成后可以使用 protoc
命令编译 proto
文件,如编译示例中的 addressbook.proto
.
protoc --java_out=./java ./resources/addressbook.proto# --java_out 指定输出 java 格式文件,输出到 ./java 目录# ./resources/addressbook.proto 为 proto 文件位置
生成后可以看到生产的类文件。
./├── java│ └── com│ └── wdbyte│ └── tool│ ├── protos│ │ ├── AddressBook.java│ │ ├── AddressBookOrBuilder.java│ │ ├── AddressBookProtos.java│ │ ├── Person.java│ │ ├── PersonOrBuilder.java└── resources ├── addressbook.proto
使用 Protobuf使用 Java 语言操作 Protobuf,首先需要引入 Protobuf 依赖。
Maven 依赖:
com.google.protobuf protobuf-java 3.22.3
构造消息对象// 直接构建PhoneNumber phoneNumber1 = PhoneNumber.newBuilder().setNumber("18388888888").setType(PhoneType.HOME).build();Person person1 = Person.newBuilder().setId(1).setName("www.wdbyte.com").setEmail("xxx@wdbyte.com").addPhones(phoneNumber1).build();AddressBook addressBook1 = AddressBook.newBuilder().addPeople(person1).build();System.out.println(addressBook1);System.out.println("------------------");// 链式构建AddressBook addressBook2 = AddressBook .newBuilder() .addPeople(Person.newBuilder() .setId(2) .setName("www.wdbyte.com") .setEmail("yyy@126.com") .addPhones(PhoneNumber.newBuilder() .setNumber("18388888888") .setType(PhoneType.HOME) ) ) .build();System.out.println(addressBook2);
输出:
people { id: 1 name: "www.wdbyte.com" email: "xxx@wdbyte.com" phones { number: "18388888888" type: HOME }}------------------people { id: 2 name: "www.wdbyte.com" email: "yyy@126.com" phones { number: "18388888888" type: HOME }}
序列化、反序列化序列化:将内存中的数据对象序列化为二进制数据,可以用于网络传输或存储等场景。
反序列化:将二进制数据反序列化成内存中的数据对象,可以用于数据处理和业务逻辑。
下面演示使用 Protobuf 进行字符数组和文件的序列化及反序列化过程。
package com.wdbyte.tool.protos;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/** * * @author www.wdbyte.com */public class ProtobufTest2 { public static void main(String[] args) throws IOException { PhoneNumber phoneNumber1 = PhoneNumber.newBuilder().setNumber("18388888888").setType(PhoneType.HOME).build(); Person person1 = Person.newBuilder().setId(1).setName("www.wdbyte.com").setEmail("xxx@wdbyte.com").addPhones(phoneNumber1).build(); AddressBook addressBook1 = AddressBook.newBuilder().addPeople(person1).build(); // 序列化成字节数组 byte[] byteArray = addressBook1.toByteArray(); // 反序列化 - 字节数组转对象 AddressBook addressBook2 = AddressBook.parseFrom(byteArray); System.out.println("字节数组反序列化:"); System.out.println(addressBook2); // 序列化到文件 addressBook1.writeTo(new FileOutputStream("AddressBook1.txt")); // 读取文件反序列化 AddressBook addressBook3 = AddressBook.parseFrom(new FileInputStream("AddressBook1.txt")); System.out.println("文件读取反序列化:"); System.out.println(addressBook3); }}
输出:
字节数组反序列化:people { id: 1 name: "www.wdbyte.com" email: "xxx@wdbyte.com" phones { number: "18388888888" type: HOME }}文件读取反序列化:people { id: 1 name: "www.wdbyte.com" email: "xxx@wdbyte.com" phones { number: "18388888888" type: HOME }}
Protobuf 为什么高效在分析 Protobuf 高效之前,我们先确认一下 Protobuf 是否真的高效,下面将 Protobuf 与 JSON 进行对比,分别对比序列化和反序列化速度以及序列化后的存储占用大小。
测试工具:JMH,FastJSON,
测试对象:Protobuf 的 addressbook.proto
,JSON 的普通 Java 类。
Maven 依赖:
com.alibaba fastjson 2.0.7 org.openjdk.jmh jmh-core 1.33 org.openjdk.jmh jmh-generator-annprocess 1.33 provided
先编写与addressbook.proto
结构相同的 Java 类 AddressBookJava.java
.
public class AddressBookJava { List personJavaList; public static class PersonJava { private int id; private String name; private String email; private PhoneNumberJava phones; // get...set... } public static class PhoneNumberJava { private String number; private PhoneTypeJava phoneTypeJava; // get....set.... } public enum PhoneTypeJava { MOBILE, HOME, WORK; } public List getPersonJavaList() { return personJavaList; } public void setPersonJavaList(List personJavaList) { this.personJavaList = personJavaList; }}
序列化大小对比分别在地址簿中添加 1000 个人员信息,输出序列化后的数组大小。
package com.wdbyte.tool.protos;import java.io.IOException;import java.util.ArrayList;import com.alibaba.fastjson.JSON;import com.wdbyte.tool.protos.AddressBook.Builder;import com.wdbyte.tool.protos.AddressBookJava.PersonJava;import com.wdbyte.tool.protos.AddressBookJava.PhoneNumberJava;import com.wdbyte.tool.protos.AddressBookJava.PhoneTypeJava;import com.wdbyte.tool.protos.Person.PhoneNumber;import com.wdbyte.tool.protos.Person.PhoneType;/** * @author https://www.wdbyte.com */public class ProtobufTest3 { public static void main(String[] args) throws IOException { AddressBookJava addressBookJava = createAddressBookJava(1000); String jsonString = JSON.toJSONString(addressBookJava); System.out.println("json string size:" + jsonString.length()); AddressBook addressBook = createAddressBook(1000); byte[] addressBookByteArray = addressBook.toByteArray(); System.out.println("protobuf byte array size:" + addressBookByteArray.length); } public static AddressBook createAddressBook(int personCount) { Builder builder = AddressBook.newBuilder(); for (int i = 0; i < personCount; i++) { builder.addPeople(Person.newBuilder() .setId(i) .setName("www.wdbyte.com") .setEmail("xxx@126.com") .addPhones(PhoneNumber.newBuilder() .setNumber("18333333333") .setType(PhoneType.HOME) ) ); } return builder.build(); } public static AddressBookJava createAddressBookJava(int personCount) { AddressBookJava addressBookJava = new AddressBookJava(); addressBookJava.setPersonJavaList(new ArrayList<>()); for (int i = 0; i < personCount; i++) { PersonJava personJava = new PersonJava(); personJava.setId(i); personJava.setName("www.wdbyte.com"); personJava.setEmail("xxx@126.com"); PhoneNumberJava numberJava = new PhoneNumberJava(); numberJava.setNumber("18333333333"); numberJava.setPhoneTypeJava(PhoneTypeJava.HOME); personJava.setPhones(numberJava); addressBookJava.getPersonJavaList().add(personJava); } return addressBookJava; }}
输出:
json string size:108910protobuf byte array size:50872
可见测试中 Protobuf 的序列化结果比 JSON 小了将近一倍左右。
序列化速度对比使用 JMH 进行性能测试,分别测试 JSON 的序列化和反序列以及 Protobuf 的序列化和反序列化性能情况。每次测试前进行 3 次预热,每次 3 秒。接着进行 5 次测试,每次 3 秒,收集测试情况。
package com.wdbyte.tool.protos;import java.util.ArrayList;import java.util.concurrent.TimeUnit;import com.alibaba.fastjson.JSON;import com.google.protobuf.InvalidProtocolBufferException;import com.wdbyte.tool.protos.AddressBook.Builder;import com.wdbyte.tool.protos.AddressBookJava.PersonJava;import com.wdbyte.tool.protos.AddressBookJava.PhoneNumberJava;import com.wdbyte.tool.protos.AddressBookJava.PhoneTypeJava;import com.wdbyte.tool.protos.Person.PhoneNumber;import com.wdbyte.tool.protos.Person.PhoneType;import org.openjdk.jmh.annotations.Benchmark;import org.openjdk.jmh.annotations.BenchmarkMode;import org.openjdk.jmh.annotations.Fork;import org.openjdk.jmh.annotations.Measurement;import org.openjdk.jmh.annotations.Mode;import org.openjdk.jmh.annotations.OutputTimeUnit;import org.openjdk.jmh.annotations.Scope;import org.openjdk.jmh.annotations.Setup;import org.openjdk.jmh.annotations.State;import org.openjdk.jmh.annotations.Warmup;/** * @author https://www.wdbyte.com */@State(Scope.Thread)@Fork(2)@Warmup(iterations = 3, time = 3)@Measurement(iterations = 5, time = 3)@BenchmarkMode(Mode.Throughput) // Throughput:吞吐量,SampleTime:采样时间@OutputTimeUnit(TimeUnit.MILLISECONDS)public class ProtobufTest4 { private AddressBookJava addressBookJava; private AddressBook addressBook; @Setup public void init() { addressBookJava = createAddressBookJava(1000); addressBook = createAddressBook(1000); } @Benchmark public AddressBookJava testJSON() { // 转 JSON String jsonString = JSON.toJSONString(addressBookJava); // JSON 转对象 return JSON.parseObject(jsonString, AddressBookJava.class); } @Benchmark public AddressBook testProtobuf() throws InvalidProtocolBufferException { // 转 JSON byte[] addressBookByteArray = addressBook.toByteArray(); // JSON 转对象 return AddressBook.parseFrom(addressBookByteArray); } public static AddressBook createAddressBook(int personCount) { Builder builder = AddressBook.newBuilder(); for (int i = 0; i < personCount; i++) { builder.addPeople(Person.newBuilder() .setId(i) .setName("www.wdbyte.com") .setEmail("xxx@126.com") .addPhones(PhoneNumber.newBuilder() .setNumber("18333333333") .setType(PhoneType.HOME) ) ); } return builder.build(); } public static AddressBookJava createAddressBookJava(int personCount) { AddressBookJava addressBookJava = new AddressBookJava(); addressBookJava.setPersonJavaList(new ArrayList<>()); for (int i = 0; i < personCount; i++) { PersonJava personJava = new PersonJava(); personJava.setId(i); personJava.setName("www.wdbyte.com"); personJava.setEmail("xxx@126.com"); PhoneNumberJava numberJava = new PhoneNumberJava(); numberJava.setNumber("18333333333"); numberJava.setPhoneTypeJava(PhoneTypeJava.HOME); personJava.setPhones(numberJava); addressBookJava.getPersonJavaList().add(personJava); } return addressBookJava; }}
JMH 吞吐量测试结果(Score 值越大吞吐量越高,性能越好):
Benchmark Mode Cnt Score Error UnitsProtobufTest3.testJSON thrpt 10 1.877 ± 0.287 ops/msProtobufTest3.testProtobuf thrpt 10 2.813 ± 0.446 ops/ms
JMH 采样时间测试结果(Score 越小,采样时间越小,性能越好):
Benchmark Mode Cnt Score Error UnitsProtobufTest3.testJSON sample 53028 0.565 ± 0.005 ms/opProtobufTest3.testProtobuf sample 90413 0.332 ± 0.001 ms/op
从测试结果看,不管是吞吐量测试,还是采样时间测试,Protobuf 都优于 JSON。
为什么高效?Protobuf 是如何实现这种高效紧凑的数据编码和解码的呢?
首先,Protobuf 使用二进制编码,会提高性能;其次 Protobuf 在将数据转换成二进制时,会对字段和类型重新编码,减少空间占用。它采用 TLV
格式来存储编码后的数据。TLV
也是就是 Tag-Length-Value,是一种常见的编码方式,因为数据其实都是键值对形式,所以在 TAG
中会存储对应的字段和类型信息,Length
存储内容的长度,Value
存储具体的内容。
还记得上面定义结构体时每个字段都对应一个数字吗?如 =1
,=2
,=3
.
message Person { optional int32 id = 1; optional string name = 2; optional string email = 3;}
在序列化成二进制时候就是通过这个数字来标记对应的字段的,二进制中只存储这个数字,反序列化时通过这个数字找对应的字段。这也是上面为什么说尽量使用 1-15 范围内的数字,因为一旦超过 15,就需要多一个 bit 位来存储。
那么类型信息呢?比如 int32
怎么标记,因为类型个数有限,所以 Protobuf 规定了每个类型对应的二进制编码,比如 int32
对应二进制 000
,string
对应二进制 010
,这样就可以只用三个比特位存储类型信息。
这里只是举例描述大概思想,具体还有一些变化。
详情可以参考官方文档:https://protobuf.dev/programming-guides/encoding/
其次,Protobuf 还会采用一种变长编码的方式来存储数据。这种编码方式能够保证数据占用的空间最小化,从而减少了数据传输和存储的开销。具体来说,Protobuf 会将整数和浮点数等类型变换成一个或多个字节的形式,其中每个字节都包含了一部分数据信息和一部分标识符信息。这种编码方式可以在数据值比较小的情况下,只使用一个字节来存储数据,以此来提高编码效率。
最后,Protobuf 还可以通过采用压缩算法来减少数据传输的大小。比如 GZIP 算法能够将原始数据压缩成更小的二进制格式,从而在网络传输中能够节省带宽和传输时间。Protobuf 还提供了一些可选的压缩算法,如 zlib 和 snappy,这些算法在不同的场景下能够适应不同的压缩需求。
综上所述,Protobuf 在实现高效编码和解码的过程中,采用了多种优化方式,从而在实际应用中能够有效地提升数据传输和处理的效率。
总结ProtoBuf 是一种轻量、高效的数据交换格式,它具有以下优点:
语言中立,可以支持多种编程语言;数据结构清晰,易于维护和扩展;二进制编码,数据体积小,传输效率高;自动生成代码,开发效率高。但是,ProtoBuf 也存在以下缺点:
学习成本较高,需要掌握其语法规则和使用方法;需要先定义数据结构,然后才能对数据进行序列化和反序列化,增加了一定的开发成本;由于二进制编码,可读性较差,这点不如 JSON 可以直接阅读。总体来说,Protobuf 适合用于数据传输和存储等场景,能够提高数据传输效率和减少数据体积。但对于需要人类可读的数据,或需要实时修改的数据,或者对数据的传输效率和体积没那么在意的场景,选择更加通用的 JSON 未尝不是一个好的选择。
参考:https://protobuf.dev/overview/
一如既往,文章代码都存放在 Github.com/niumoo/javaNotes.
文章持续更新,可以微信搜一搜「 程序猿阿朗 」或访问「程序猿阿朗博客 」第一时间阅读。本文 Github.com/niumoo/JavaNotes 已经收录,有很多系列文章,欢迎Star。
标签:
- 知识课堂 校园欺凌是什么
- 权威百科知识 双氧水是啥东西
- 生活知识 长颈鹿是什么动物
- 知识导航 涤纶是什么
- 经验分享 嵌入式什么意思
- 百科 梦醒时分粤语版叫什么
- 打破性别“玻璃天花板” 95岁女院士是“她力量”最佳代言
- 中国记者节|今天,一起揭秘他们的独门“武功秘籍”
- 内蒙古通辽遭遇特大暴雪:学校停课 机场关闭
- 河北辛集市暂停举办体育活动 关闭景区文娱场所
- 红色文物·党史故事 “推出胜利”的小推车
- 侵华日军南京大屠杀遇难同胞纪念馆闭馆
- 甘肃:已治愈出院18例 闭环健康管理助回归家庭
- 核酸采样:一位“点长”的50小时冲刺
- 跑道结冰 哈尔滨机场关闭至9日12时
- 辽宁大连迎今冬首场降雪 机场临时关闭跑道地铁3号线停运
- 北京地铁全面开启车内加热装置
- 黑河市多举措保障疫情期间残疾人等特殊群体生活稳定
- 北京丰台海淀两处管控区域解封 社区工作者收到“暖心礼物”
- 百年兰州牛肉面的“隔离与亲近”
- 暴雪侵袭黑龙江 9地市最大雪深17厘米
- 吉林四平一旅游项目违占耕地两千多亩 投资达10亿元
- 湖南双峰27名非法滞留缅北人员被惩戒:小孩回原籍入学
- 江西新增本土“1+6” 上饶增一中风险地区
- 江西上饶一地调整为中风险地区 实行封闭管理措施
- 西宁市主城区首轮全员核酸采集样本144.8万份 结果均为阴性
- 快递旺季遭遇雨雪天气 国家邮政局呼吁理解快递小哥
- 高压、孤独,胆大、心细:手执焊枪的水下“蛙人”
- 掏粪掏了36年,他还在琢磨“新门道”
- 内蒙古:二连浩特市新增1例本土确诊病例 额济纳旗累计治愈出院本土确诊病例76例
- 坚守在海拔4300多米的“天路保健医生”
- 38年后,他终于知道了家在哪儿……
- 受降雪影响 辽宁鞍山一农贸市场发生坍塌
- 中国舞蹈家协会顶尖教师巡回课堂(重庆站)举办
- 边城战“疫”:夜晚七点的暂停键
- 风雪高原战“疫”长卷 寒潮下的西宁疫情防控观察
- 拟音师:“雕刻”声音的人【三百六十行】
- “双减”之后 中小学教师资格考试为何依然火爆
- 大数据助力贫困生成长
- “大漠明珠”驶上发展快车道 塔里木盆地做足生态大文章
- 职校生可报考事业单位 搬走职业教育的一块绊脚石
- 打算“双十一”买买买的姐妹 看完这篇再“剁手”
- 完美“飞天”仰仗全宇宙最酷飞船试驾员
- 冠状病毒中损伤血管的蛋白首次确定
- 新电池结构让飞行汽车成为可能 相关技术将亮相北京冬奥
- H5N8病毒肆虐全球,我国家禽为何“独善其身”
- 重庆奉节一民警因公殉职 年仅28岁
- 哈尔滨市新增本土新冠肺炎确诊病例1例
- 成都本地累计在管密接2757人、次密9097人
- 成都累计报告确诊病例23例 出现1传13特殊案例
-
呼和浩特一学校宿管员扇打学生致双耳鼓膜穿孔 分管校长被免
中新网呼和浩特11月9日电 (记者 张林虎)9日,针对“宿管员扇打学生致其双耳鼓膜穿孔”一事,呼和...
-
郑州通报8例确诊病例和无症状感染者活动轨迹
中新网11月9日电 据郑州市委宣传部官方微信消息,11月8日0至24时,郑州市新增阳性感染者3例,均为...
-
新疆阿克苏果农:我们的生活像苹果一样甜
中新社新疆阿克苏11月9日电 题:新疆阿克苏果农:我们的生活像苹果一样甜 作者 苟继鹏 “我...
-
河北辛集开展大规模消毒消杀工作
今天(9日)上午,河北省辛集市召开疫情防控新闻发布会。会上,辛集市科学技术局局长辛彦卜介绍,新冠...
-
河北辛集新增本土确诊11例 已转运定点医院诊治
今天(9日)上午,河北省辛集市召开疫情防控新闻发布会,辛集市副市长刘士民介绍,2021年11月8日0时至...
-
石家庄深泽县第五轮全员核酸检测结果全部为阴性
11月9日,石家庄市召开第12场新冠肺炎疫情防控工作新闻发布会。发布会上,石家庄市深泽县县长郝英鹏...
-
海口市1例治愈后的境外输入病例复阳 已转至定点医院隔离医学观察
中新网海口11月8日电 (记者 张茜翼)海口市新型冠状病毒感染肺炎疫情防控工作指挥部8日通报称,11...
-
四川新增本土确诊病例4例
中新网11月8日电 据四川省卫健委网站消息,11月7日0-24时,四川新增新型冠状病毒肺炎确诊病例5例(...
-
黑龙江省新增新冠肺炎本土确诊病例6例
中新网哈尔滨11月8日电 (程岩 记者 史轶夫)黑龙江省卫健委8日发布消息,7日0-24时,黑龙江省黑河...
-
河南新增本土确诊病例18例 其中郑州市16例周口市2例
中新网11月8日电 据河南省卫健委官方微博消息,11月7日0—24时,河南省新增本土确诊病例18例(郑州...
-
河北新增确诊病例8例 新增无症状感染者1例
中新网11月8日电 据河北省卫健委网站消息,2021年11月7日0—24时,河北省新增新型冠状病毒肺炎确诊...
-
寒潮持续发威!南方气温纷纷触底 强降雪中心转移至东北
中国天气网讯 今天(11月8日),寒潮继续南下,持续发威,南方大部最高气温将纷纷触底。强降雪中心将...
-
雪后寒!今日北京晴天回归北风劲吹 最高气温5℃上下
中国天气网讯 今天(11月8日)北京晴天回归,但在风寒效应下,“冷”仍然是天气的主题。气温方面,今...
-
黑龙江新增本土确诊病例6例 均在黑河市爱辉区
中新网11月8日电 据黑龙江省卫健委网站消息,2021年11月7日0-24时,黑龙江省新增新冠肺炎本土确诊...
-
寒潮继续影响华东华南等地 东北地区等地有强降雪
中新网11月8日电 据中央气象台网站消息,受寒潮影响,预计11月8日08时至9日08时,黄淮东部、江淮东...
-
辽宁新增本土确诊病例20例 新增本土无症状感染者12例
中新网11月8日电 据辽宁省卫健委网站消息,11月7日0时至24时,辽宁省新增20例本土新冠肺炎确诊病例...
-
寒潮影响“加码”:吉林力保电力供应 停课停运范围加大
中新网长春11月9日电 (记者 郭佳 张瑶)连日来,一轮寒潮引发的强降雪席卷中国北方。位于东北地区...
-
常州连续一周无新增病例 10日全市各类学校将错峰复学
中新网常州11月9日电 (记者 唐娟)11月9日,常州疫情防控指挥部学校防控组对外发布,自11月10起,...
-
哈尔滨机场开放恢复运行 计划航班45架次
中新网哈尔滨11月9日电 (仇建 记者 史轶夫)9日12时22分,随着哈尔滨经阜阳飞往三亚的FU6685航班...
-
山西警方抓获6名“摸金校尉” 缴获“虎枕”等大量文物
中新网长治11月9日电 (记者 李庭耀)记者9日从山西省长治市公安局上党分局获悉,上党警方侦破系列...
-
西藏基层第一书记话产业发展推进乡村振兴
中新网日喀则11月9日电(记者 赵朗)近日,由西藏自治区网信办主办的第一书记话小康活动先后走进山南...
-
内蒙古通辽:强降雪致8个旗县区受灾
中新网通辽11月9日电 (记者 张林虎)9日,记者从内蒙古自治区通辽市应急管理局获悉,自11月5日起,...
-
成都金堂:医护人取消婚礼坚守岗位 手捧花被送到了战“疫”一线
中新网成都11月9日电 (邹立杨)连日来,华西医院金堂县第一人民医院实验医学科的主检验师易维佳都在...
-
江西铅山新一轮核酸检测结果均为阴性
(抗击新冠肺炎)江西铅山新一轮核酸检测结果均为阴性 中新网南昌11月9日电 (记者 吴鹏泉)江西省...
-
辽宁大连幼儿园和中小学学生即日起暂缓入校
中新网11月9日电 据辽宁省大连市人民政府新闻办公室官方微博消息,大连市新冠肺炎疫情防控总指挥部...
-
那年今日 | 一张漫画涨知识之11月8日
-
北京新增1例本土确诊病例
中新网11月8日电 据北京卫健委官方微博消息,11月7日0时至24时,北京新增1例本土确诊病例,无新增...
-
河北石家庄深泽县7日新增1例无症状感染者 为8岁男童
中新网11月8日电 据石家庄卫健委官方微信消息,石家庄深泽县应对新冠肺炎疫情工作领导小组办公室8...
-
高速封闭、机场关闭、学校停课 辽宁多部门发应急预案应对极端天气
中新网沈阳11月8日电 (李晛 王景巍)7日在寒潮影响下,东北地区局地降大雪。辽宁省气象部门当日连...
-
云南新增本土确诊病例3例 新增本土无症状感染者3例
中新网11月8日电 据云南省卫健委网站消息,11月7日0—24时,云南省新增确诊病例9例,其中境外输入...
-
努力让每个人都有出彩机会
努力让每个人都有出彩机会 “孩子明年要参加中考,成绩一直提不上去,送他读职高,也是一种选择...
-
参与和见证中国水电发展
参与和见证中国水电发展 余吉安的童年是在马来西亚加里曼丹岛的沙捞越州古晋市度过的。家门口的...
-
中国航天:为实现中国梦提供战略支撑
中国航天:为实现中国梦提供战略支撑(科技名家笔谈) 今年是中国共产党成立100周年,也是中国航...
-
8日起 江西铅山县开展新一轮全员核酸检测
记者从江西省铅山县疫情防控指挥部了解到,按照疫情防控要求,为了充分保障公众的健康安全,现定于1...
-
适当“早教”可以,“早早教”大可不必
一家之言 适当“早教”可以,“早早教”大可不必 以前国庆节是放假了,可家家都有娃,放假补...
X 关闭
X 关闭