展开

关键词

首页关键词metaprogramming

metaprogramming

相关内容

云服务器

云服务器

腾讯云服务器(CVM)为您提供安全可靠的弹性云计算服务。只需几分钟,您就可以在云端获取和启用云服务器,并实时扩展或缩减云计算资源。云服务器 支持按实际使用的资源计费,可以为您节约计算成本。
  • 来来来,咱们元编程入个门

    那么本文就干一些,尝试用粗浅的语言对 metaprogramming macro 做个小小的入门,主要是讲清楚一些概念和思想。文字代码一起上,酒干倘卖无。之前的文章已经给了一个将问题抽象成规则,然后针对规则编程的例子,虽然它可以被称为广义的 metaprogramming,但为了定义清晰,我们还是看看 wikipedia 怎么解释 metaprogramming这涉及到 metaprogramming 的第一个重要的概念:Abstract Syntax Tree,抽象语法树(以下简称 AST,或者语法树)。从这个角度来说,metaprogramming 的能力:lisp >= elixir >> ruby > python >> javac# >> cc++。在使用 macro 进行 metaprogramming 时,最常见的一个坑是表达式的反复求值。我们看一个函数:?
    来自:
    浏览:427
  • Python Metaclass 初探

    meta的意思就是“关于什么的什么”:比如metadata可以理解为“关于数据的数据”,metaprogramming可以理解为“关于编程的编程”。这就和“更高一层的抽象” 比较契合了。实例聚焦到我们今天的主题,metaprogramming就是编写用来生成代码的代码。string with self.assertRaises(TypeError): s.split(2) if __name__ == __main__: unittest.main()所以我们的目的就是用metaprogramming但是当你要表达的逻辑比较复杂的时候,metaprogramming的强大就体现出来了。总结那么,看完这篇文章,我们也成为Tim所说的1%的程序猿了!在一些特殊的场合,比如编写某种框架的时候,metaprogramming会做到事半功倍。祝你在实践中碰到这样的机会。
    来自:
    浏览:200
  • 广告
    关闭

    2021 V+全真互联网全球创新创业挑战赛

    百万资源,六大权益,启动全球招募

  • 您找到你想要的搜索结果了吗?
    是的
    没有找到
  • Scala Macros - 元编程 Metaprogramming with Def Macros

        Scala Macros对scala函数库编程人员来说是一项不可或缺的编程工具,可以通过它来解决一些用普通编程或者类层次编程(type level programming)都无法解决的问题,这是因为Scala Macros可以直接对程序进行修改。Scala Macros的工作原理是在程序编译时按照编程人员的意旨对一段程序进行修改产生出一段新的程序。具体过程是:当编译器在对程序进行类型验证(typecheck)时如果发现Macro标记就会将这个Macro的功能实现程序(implementation):一个语法树(AST, Abstract Syntax Tree)结构拉过来在Macro的位置进行替代,然后从这个AST开始继续进行类型验证过程。下面我们先用个简单的例子来示范分析一下Def Macros的基本原理和使用方法:1 object modules {2 greeting(john)3 }4 5 object mmacros {6 def greeting(person: String): Unit = macro greetingMacro7 def greetingMacro(c: Context)(person: c.Expr): c.Expr = ...8 }以上是Def Macros的标准实现模式。基本原理是这样的:当编译器在编译modules遇到方法调用greeting(john)时会进行函数符号解析、在mmacros里发现greeting是个macro,它的具体实现在greetingMacro函数里,此时编译器会运行greetingMacro函数并将运算结果-一个AST调用替代表达式greeting(john)。注意编译器在运算greetingMacro时会以AST方式将参数person传入。由于在编译modules对象时需要运算greetingMacro函数,所以greetingMacro函数乃至整个mmacros对象必须是已编译状态,这就意味着modules和mmacros必须分别在不同的源代码文件里,而且还要确保在编译modules前先完成对mmacros的编译,我们可以从sbt设置文件build.sbt看到它们的关系: 1 name := learn-macro 2 3 version := 1.0.1 4 5 val commonSettings = Seq( 6 scalaVersion := 2.11.8, 7 scalacOptions ++= Seq(-deprecation, -feature), 8 libraryDependencies ++= Seq( 9 org.scala-lang % scala-reflect % scalaVersion.value,10 org.scala-lang.modules %% scala-parser-combinators % 1.0.1,11 org.specs2 %% specs2 % 2.3.12 % test,12 org.scalatest % scalatest_2.11 % 2.2.1 % test13 ),14 addCompilerPlugin(org.scalamacros % paradise % 2.1.0 cross CrossVersion.full)15 )16 17 lazy val root = (project in file(.)).aggregate(macros, demos)18 19 lazy val macros = project.in(file(macros)).settings(commonSettings : _*)20 21 lazy val demos = project.in(file(demos)).settings(commonSettings : _*).dependsOn(macros)注意最后一行:demos dependsOn(macros),因为我们会把所有macros定义文件放在macros目录下。下面我们来看看macro的具体实现方法: 1 import scala.language.experimental.macros 2 import scala.reflect.macros.blackbox.Context 3 import java.util.Date 4 object LibraryMacros { 5 def greeting(person: String): Unit = macro greetingMacro 6 7 def greetingMacro(c: Context)(person: c.Expr): c.Expr = { 8 import c.universe._ 9 println(compiling greeting ...)10 val now = reify {new Date().toString}11 reify {12 println(Hello + person.splice + , the time is: + new Date().toString)13 }14 }15 }以上是macro greeting的具体声明和实现。代码放在macros目录下的MacrosLibrary.scala里。首先必须import macros和Context。macro调用在demo目录下的HelloMacro.scala里:1 object HelloMacro extends App {2 import LibraryMacros._3 greeting(john)4 }注意在编译HelloMacro.scala时产生的输出:Mac-Pro:learn-macro tiger-macpro$ sbt Loading global plugins from Userstiger-macpro.sbt0.13plugins Loading project definition from Userstiger-macproScalaIntelliJlearn-macroproject Set current project to learn-macro (in build file:Userstiger-macproScalaIntelliJlearn-macro)> project demos Set current project to demos (in build file:Userstiger-macproScalaIntelliJlearn-macro)> compile Compiling 1 Scala source to Userstiger-macproScalaIntelliJlearn-macromacrostargetscala-2.11classes... compiler-interface not yet compiled for Scala 2.11.8. Compiling... Compilation completed in 7.876 s Compiling 1 Scala source to Userstiger-macproScalaIntelliJlearn-macrodemostargetscala-2.11classes...compiling greeting ... Total time: 10 s, completed 2016-11-9 9:28:24> 从compiling greeting ...这条提示我们可以得出在编译demo目录下源代码文件的过程中应该运算了greetingMacro函数。测试运行后产生结果:Hello john, the time is: Wed Nov 09 09:32:04 HKT 2016 Process finished with exit code 0运算greeting实际上是调用了greetingMacro中的macro实现代码。上面这个例子使用了最基础的Scala Macro编程模式。注意这个例子里函数greetingMacro的参数c: Context和在函数内部代码中reify,splice的调用:由于Context是个动态函数接口,每个实例都有所不同。对于大型的macro实现函数,可能会调用到其它同样会使用到Context的辅助函数(helper function),容易出现Context实例不匹配问题。另外reify和splice可以说是最原始的AST操作函数。我们在下面这个例子里使用了最新的模式和方法: 1 def tell(person: String): Unit = macro MacrosImpls.tellMacro 2 class MacrosImpls(val c: Context) { 3 import c.universe._ 4 def tellMacro(person: c.Tree): c.Tree = { 5 println(compiling tell ...) 6 val now = new Date().toString 7 q 8 println(Hello +$person+, it is: +$now) 9 10 }11 }在这个例子里我们把macro实现函数放入一个以Context为参数的class。我们可以把所有使用Context的函数都摆在这个class里面大家共用统一的Context实例。quasiquotes是最新的AST操作函数集,可以更方便灵活地控制AST的产生、表达式还原等。这个tell macro的调用还是一样的:1 object HelloMacro extends App {2 import LibraryMacros._3 greeting(john)4 tell(mary)5 }测试运算产生下面的结果:Hello john, the time is: Wed Nov 09 11:42:21 HKT 2016Hello mary, it is: Wed Nov 09 11:42:20 HKT 2016 Process finished with exit code 0Def Macros的Macro实现函数可以是泛型函数,支持类参数。在下面的例子我们示范如何用Def Macros来实现通用的case class与Map类型的转换。假设我们有个转换器CaseClassMapConverter,那么C类型可以是任何case class,所以这个转换器是泛型的,那么macro实现函数也就必须是泛型的了。大体来说,我们希望实现以下功能:把任何case class转成Map: 1 def ccToMap(c: C): Map = 2 implicitly].toMap(c) 3 4 case class Person(name: String, age: Int) 5 case class Car(make: String, year: Int, manu: String) 6 7 val civic = Car(Civic,2016,Honda) 8 println(ccToMap(Person(john,18))) 9 println(ccToMap(civic))10 11 ...12 Map(name -> john, age -> 18)13 Map(make -> Civic, year -> 2016, manu -> Honda)反向把Map转成case class: 1 def mapTocc(m: Map) = 2 implicitly].fromMap(m) 3 4 val mapJohn = ccToMap(Person(john,18)) 5 val mapCivic = ccToMap(civic) 6 println(mapTocc(mapJohn)) 7 println(mapTocc(mapCivic)) 8 9 ...10 Person(john,18)11 Car(Civic,2016,Honda)我们来看看这个Macro的实现函数:macrosCaseClassConverter.scala 1 import scala.language.experimental.macros 2 import scala.reflect.macros.whitebox.Context 3 4 trait CaseClassMapConverter { 5 def toMap(c: C): Map 6 def fromMap(m: Map): C 7 } 8 object CaseClassMapConverter { 9 implicit def Materializer: CaseClassMapConverter = macro converterMacro10 def converterMacro(c: Context): c.Tree = {11 import c.universe._12 13 val tpe = weakTypeOf14 val fields = tpe.decls.collectFirst {15 case m: MethodSymbol if m.isPrimaryConstructor => m16 }.get.paramLists.head17 18 val companion = tpe.typeSymbol.companion19 val (toParams,fromParams) = fields.map { field =>20 val name = field.name.toTermName21 val decoded = name.decodedName.toString22 val rtype = tpe.decl(name).typeSignature23 24 (q$decoded -> t.$name, qmap($decoded).asInstanceOf)25 26 }.unzip27 28 q29 new CaseClassMapConverter {30 def toMap(t: $tpe): Map = Map(..$toParams)31 def fromMap(map: Map): $tpe = $companion(..$fromParams)32 }33 34 }35 }首先,trait CaseClassMapConverter是个typeclass,代表了C类型数据的行为函数toMap和fromMap。我们同时可以看到Macro定义implicit def Materializer是隐式的,而且是泛型的,运算结果类型是CaseClassMapConverter。从这个可以推断出这个Macro定义通过Macro实现函数可以产生CaseClassMapConverter实例,C可以是任何case class类型。在函数ccToMap和mapTocc函数需要的隐式参数CaseClassMapConverter实例就是由这个Macro实现函数提供的。注意我们只能用WeakTypeTag来获取类型参数C的信息。在使用quasiquotes时我们一般是在q括号中放入原始代码。在q括号内调用AST变量用$前缀(称为unquote)。对类型tpe的操作可以参考scala.reflect api。示范调用代码在demo目录下的ConverterDemo.scala里: 1 import CaseClassMapConverter._ 2 object ConvertDemo extends App { 3 4 def ccToMap(c: C): Map = 5 implicitly].toMap(c) 6 7 case class Person(name: String, age: Int) 8 case class Car(make: String, year: Int, manu: String) 9 10 val civic = Car(Civic,2016,Honda)11 println(ccToMap(Person(john,18)))12 println(ccToMap(civic))13 14 def mapTocc(m: Map) =15 implicitly].fromMap(m)16 17 val mapJohn = ccToMap(Person(john,18))18 val mapCivic = ccToMap(civic)19 println(mapTocc(mapJohn))20 println(mapTocc(mapCivic))21 22 }在上面这个implicit Macros例子里引用了一些quasiquote语句(qxxx)。quasiquote是Scala Macros的一个重要部分,主要替代了原来reflect api中的reify功能,具备更强大、方便灵活的处理AST功能。Scala Def Macros还提供了Extractor Macros,结合Scala String Interpolation和模式匹配来提供compile time的extractor object生成。Extractor Macros的具体用例如下:1 import ExtractorMicros._2 val fname = William3 val lname = Wang4 val someuser = usr$fname,$lname new FreeUser(William,Wang)5 6 someuser match {7 case usr$first,$last => println(shello $first $last)8 }在上面这个例子里usr???的usr是一个pattern和extractor object。与通常的string interpolation不同的是usr不是一个方法(method),而是一个对象(object)。这是由于模式匹配中的unapply必须在一个extractor object内,所以usr是个object。我们知道一个object加上它的apply可以当作method来调用。也就是说如果在usr object中实现了apply就可以用usr(???)作为method使用,如下:1 implicit class UserInterpolate(sc: StringContext) {2 object usr {3 def apply(args: String*): Any = macro UserMacros.appl4 def unapply(u: User): Any = macro UserMacros.uapl5 }6 }通过Def Macros在编译过程中自动生成apply和unapply,它们分别对应了函数调用:val someuser = usr$fname,$lname case usr$first,$last => println(shello $first $last)下面是macro appl的实现:1 def appl(c: Context)(args: c.Tree*) = {2 import c.universe._3 val arglist = args.toList4 qnew FreeUser(..$arglist)5 }主要通过qnew FreeUser(arg1,arg2)实现了个AST的构建。macro uapl的实现相对复杂些,对quasiquote的应用会更深入些。首先要确定类型的primary constructor的参数数量和名称,然后通过quasiquote的模式匹配分解出相应的sub-AST,再重新组合形成最终完整的AST: 1 def uapl(c: Context)(u: c.Tree) = { 2 import c.universe._ 3 val params = u.tpe.members.collectFirst { 4 case m: MethodSymbol if m.isPrimaryConstructor => m.asMethod 5 }.get.paramLists.head.map {p => p.asTerm.name.toString} 6 7 val (qget,qdef) = params.length match { 8 case len if len == 0 => 9 (List(q),List(q))10 case len if len == 1 =>11 val pn = TermName(params.head)12 (List(qdef get = u.$pn),List(q))13 case _ =>14 val defs = List(qdef _1 = x,qdef _2 = x,qdef _3 = x,qdef _4 = x)15 val qdefs = (params zip defs).collect {16 case (p,d) =>17 val qdef $mname = $mbody = d18 val pn = TermName(p)19 qdef $mname = u.$pn20 }21 (List(qdef get = this),qdefs)22 }23 24 q25 new {26 class Matcher(u: User) {27 def isEmpty = false28 ..$qget29 ..$qdef30 }31 def unapply(u: User) = new Matcher(u)32 }.unapply($u)33 34 }35 }前面大部分代码就是为了形成List qget和qdef,最后组合一个完整的quasiquote q new {...}。完整的Macro实现源代码如下: 1 trait User { 2 val fname: String 3 val lname: String 4 } 5 6 class FreeUser(val fname: String, val lname: String) extends User { 7 val i = 10 8 def f = 1 + 2 9 }10 class PremiumUser(val name: String, val gender: Char, val vipnum: String) extends User11 12 object ExtractorMicros {13 implicit class UserInterpolate(sc: StringContext) {14 object usr {15 def apply(args: String*): Any = macro UserMacros.appl16 def unapply(u: User): Any = macro UserMacros.uapl17 }18 }19 }20 object UserMacros {21 def appl(c: Context)(args: c.Tree*) = {22 import c.universe._23 val arglist = args.toList24 qnew FreeUser(..$arglist)25 }26 def uapl(c: Context)(u: c.Tree) = {27 import c.universe._28 val params = u.tpe.members.collectFirst {29 case m: MethodSymbol if m.isPrimaryConstructor => m.asMethod30 }.get.paramLists.head.map {p => p.asTerm.name.toString}31 32 val (qget,qdef) = params.length match {33 case len if len == 0 =>34 (List(q),List(q))35 case len if len == 1 =>36 val pn = TermName(params.head)37 (List(qdef get = u.$pn),List(q))38 case _ =>39 val defs = List(qdef _1 = x,qdef _2 = x,qdef _3 = x,qdef _4 = x)40 val qdefs = (params zip defs).collect {41 case (p,d) =>42 val qdef $mname = $mbody = d43 val pn = TermName(p)44 qdef $mname = u.$pn45 }46 (List(qdef get = this),qdefs)47 }48 49 q50 new {51 class Matcher(u: User) {52 def isEmpty = false53 ..$qget54 ..$qdef55 }56 def unapply(u: User) = new Matcher(u)57 }.unapply($u)58 59 }60 }调用示范代码: 1 object Test extends App { 2 import ExtractorMicros._ 3 val fname = William 4 val lname = Wang 5 val someuser = usr$fname,$lname new FreeUser(William,Wang) 6 7 someuser match { 8 case usr$first,$last => println(shello $first $last) 9 }10 }Macros Annotation(注释)是Def Macro重要的功能部分。对一个目标,包括类型、对象、方法等进行注释意思是在源代码编译时对它们进行拓展修改甚至完全替换。比如我们下面展示的方法注释(method annotation):假设我们有下面两个方法:1 def testMethod: Double = {2 val x = 2.0 + 2.03 Math.pow(x, x)4 }5 6 def testMethodWithArgs(x: Double, y: Double) = {7 val z = x + y8 Math.pow(z,z)9 }如果我想测试它们运行所需时间的话可以在这两个方法的内部代码前设定开始时间,然后在代码后截取完成时间,完成时间-开始时间就是运算所需要的时间了,如下:1 def testMethod: Double = {2 val start = System.nanoTime()3 4 val x = 2.0 + 2.05 Math.pow(x, x)6 7 val end = System.nanoTime()8 println(selapsed time is: ${end - start})9 }我们希望通过注释来拓展这个方法:具体做法是保留原来的代码,同时在方法内部前后增加几行代码。我们看看这个注释的目的是如何实现的: 1 def impl(c: Context)(annottees: c.Tree*): c.Tree = { 2 import c.universe._ 3 4 annottees.head match { 5 case q$mods def $mname(...$args): $rettpe = { ..$stats } => { 6 q 7 $mods def $mname(...$args): $rettpe = { 8 val start = System.nanoTime() 9 val result = {..$stats}10 val end = System.nanoTime()11 println(${mname.toString} + elapsed time in nano second = + (end-start).toString())12 result13 }14 15 }16 case _ => c.abort(c.enclosingPosition, Incorrect method signature!)17 }可以看到:我们还是用quasiquote来分拆被注释的方法,然后再用quasiquote重现组合这个方法。在重组过程中增加了时间截取和列印代码。下面这行是典型的AST模式分拆(pattern desctruction): case q$mods def $mname(...$args): $rettpe = { ..$stats } => {...}用这种方式把目标分拆成重组需要的最基本部分。Macro Annotation的实现源代码如下: 1 import scala.annotation.StaticAnnotation 2 import scala.language.experimental.macros 3 import scala.reflect.macros.blackbox.Context 4 5 class Benchmark extends StaticAnnotation { 6 def macroTransform(annottees: Any*): Any = macro Benchmark.impl 7 } 8 object Benchmark { 9 def impl(c: Context)(annottees: c.Tree*): c.Tree = {10 import c.universe._11 12 annottees.head match {13 case q$mods def $mname(...$args): $rettpe = { ..$stats } => {14 q15 $mods def $mname(...$args): $rettpe = {16 val start = System.nanoTime()17 val result = {..$stats}18 val end = System.nanoTime()19 println(${mname.toString} + elapsed time in nano second = + (end-start).toString())20 result21 }22 23 }24 case _ => c.abort(c.enclosingPosition, Incorrect method signature!)25 }26 27 }28 }注释的调用示范代码如下: 1 object annotMethodDemo extends App { 2 3 @Benchmark 4 def testMethod: Double = { 5 val start = System.nanoTime() 6 7 val x = 2.0 + 2.0 8 Math.pow(x, x) 9 10 val end = System.nanoTime()11 println(selapsed time is: ${end - start})12 }13 @Benchmark14 def testMethodWithArgs(x: Double, y: Double) = {15 val z = x + y16 Math.pow(z,z)17 }18 19 testMethod20 testMethodWithArgs(2.0,3.0)21 22 23 }有一点值得注意的是:Macro扩展是编译中遇到方法调用时发生的,而注释目标的扩展则在更早一步的方法声明时。我们下面再看注释class的例子: 1 import scala.annotation.StaticAnnotation 2 import scala.language.experimental.macros 3 import scala.reflect.macros.blackbox.Context 4 5 class TalkingAnimal(val voice: String) extends StaticAnnotation { 6 def macroTransform(annottees: Any*): Any = macro TalkingAnimal.implAnnot 7 } 8 9 object TalkingAnimal {10 def implAnnot(c: Context)(annottees: c.Tree*): c.Tree = {11 import c.universe._12 13 annottees.head match {14 case q$mods class $cname $ctorMods(..$params) extends Animal with ..$parents {$self => ..$stats} =>15 val voice = c.prefix.tree match {16 case qnew TalkingAnimal($sound) => c.eval(c.Expr(sound))17 case _ =>18 c.abort(c.enclosingPosition,19 TalkingAnimal must provide voice sample!)20 }21 val animalType = cname.toString()22 q23 $mods class $cname(..$params) extends Animal {24 ..$stats25 def sayHello: Unit =26 println(Hello, Im a + $animalType + and my name is + name + + $voice + ...)27 }28 29 case _ =>30 c.abort(c.enclosingPosition,31 Annotation TalkingAnimal only apply to Animal inherited!)32 }33 }34 }我们看到:同样还是通过quasiquote进行AST模式拆分: case q$mods class $cname $ctorMods(..$params) extends Animal with ..$parents {$self => ..$stats} =>然后再重新组合。具体使用示范如下: 1 object AnnotClassDemo extends App { 2 trait Animal { 3 val name: String 4 } 5 @TalkingAnimal(wangwang) 6 case class Dog(val name: String) extends Animal 7 8 @TalkingAnimal(miaomiao) 9 case class Cat(val name: String) extends Animal10 11 @TalkingAnimal()12 case class Carrot(val name: String)13 Error:(12,2) Annotation TalkingAnimal only apply to Animal inherited! @TalingAnimal14 Dog(Goldy).sayHello15 Cat(Kitty).sayHello16 17 } 运算结果如下:Hello, Im a Dog and my name is Goldy wangwang...Hello, Im a Cat and my name is Kitty miaomiao... Process finished with exit code 0
    来自:
    浏览:568
  • 谈谈编程思想

    但Metaprogramming不然。它跟语言的能力很有关系。狭义的metaprogramming指代码能够将代码当作数据操作,广义讲就是在接近语言级的层面写的让代码更具动态性的代码。这就是广义的metaprogramming,让代码更具动态性。狭义的metaprogramming用django的ORM来说明最好:class TagItem(models.Model): class Meta: app_label = cayman verbose_nameobject_id)复杂的Object relational mapping以这样一种declarative的方式解决了(你甚至可以将它看成一种DSL,Domain Specific Language),如果没有metaprogramming当然,就metaprogramming的能力而言,把代码完全看做数据(列表展开与求值)的lisp族语言更甚一筹。这是我为何说metaprogramming的能力和语言相关。
    来自:
    浏览:504
  • GPU 云服务器

    腾讯GPU 云服务器是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景……
    来自:
  • FPGA 云服务器

    腾讯FPGA云服务器是基于FPGA硬件可编程加速的弹性计算服务,您只需几分钟就可以获取并部署您的FPGA实例。结合IP市场提供的图片,视频,基因等相关领域的计算解决方案,提供无与伦比的计算加速能力……
    来自:
  • 专用宿主机

    专用宿主机(CDH)提供用户独享的物理服务器资源,满足您资源独享、资源物理隔离、安全、合规需求。专用宿主机搭载了腾讯云虚拟化系统,购买之后,您可在其上灵活创建、管理多个自定义规格的云服务器实例,自主规划物理资源的使用。
    来自:
  • 黑石物理服务器2.0

    腾讯黑石物理服务器2.0(CPM)是一种包年包月的裸金属云服务,为您提供云端独享的高性能、无虚拟化的、安全隔离的物理服务器集群。使用该服务,您只需根据业务特性弹性伸缩物理服务器数量,获取物理服务器的时间将被缩短至分钟级。
    来自:
  • 容器服务

    腾讯云容器服务(Tencent Kubernetes Engine ,TKE)基于原生kubernetes提供以容器为核心的、高度可扩展的高性能容器管理服务。腾讯云容器服务完全兼容原生 kubernetes API ,扩展了腾讯云的云硬盘、负载均衡等 kubernetes 插件,为容器化的应用提供高效部署、资源调度、服务发现和动态伸缩等一系列完整功能,解决用户开发、测试及运维过程的环境一致性问题,提高了大规模容器集群管理的便捷性,帮助用户降低成本,提高效率。容器服务提供免费使用,涉及的其他云产品另外单独计费。
    来自:
  • 弹性伸缩

    腾讯弹性伸缩(AS)为您提供高效管理计算资源的策略。您可设定时间周期性地执行管理策略或创建实时监控策略,来管理 CVM 实例数量,并完成对实例的环境部署,保证业务平稳顺利运行。弹性伸缩策略不仅能够让需求稳定规律的应用程序实现自动化管理,同时告别业务突增或CC攻击等带来的烦恼,对于每天、每周、每月使用量不停波动的应用程序还能够根据业务负载分钟级扩展。
    来自:
  • 云函数

    云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。SCF 是实时文件处理和数据处理等场景下理想的计算平台。
    来自:
  • 批量计算

    批量计算(Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算可以根据用户提供的批处理规模,智能地管理作业和调动所其需的最佳资源……
    来自:
  • 消息队列 CMQ

    腾讯云消息队列(CMQ)是一种分布式消息队列服务,它能够提供可靠的基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)之间的收发消息,存储在可靠有效的 CMQ 队列中,防止消息丢失。CMQ 支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
    来自:
  • 消息队列 CKafka

    CKafka(Cloud Kafka)是一个分布式的、高吞吐量、高可扩展性的消息系统,100%兼容开源 Kafka API(0.9版本)。Ckafka 基于发布/订阅模式,通过消息解耦,使生产者和消费者异步交互,无需彼此等待。Ckafka 具有数据压缩、同时支持离线和实时数据处理等优点,适用于日志压缩收集、监控数据聚合等场景。
    来自:
  • API 网关

    腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。您可使用 API 网关封装自身业务,将您的数据、业务逻辑或功能安全可靠的开放出来,用以实现自身系统集成、以及与合作伙伴的业务连接。
    来自:
  • 微服务平台 TSF

    腾讯微服务平台(TSF)是一个围绕应用和微服务的 PaaS 平台,提供一站式应用全生命周期管理能力和数据化运营支持,提供多维度应用和服务的监控数据,助力服务性能优化。
    来自:
  • 对象存储

    腾讯云对象存储数据处理方案主要针对于存储于腾讯云对象存储COS中的数据内容进行处理加工,满足压缩、转码、编辑、分析等多种诉求,激活数据价值。
    来自:
  • 文件存储

    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。CFS 可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云 CFS 的管理界面简单、易使用,可实现对现有应用的无缝集;按实际用量付费,为您节约成本,简化 IT 运维工作。
    来自:
  • 归档存储

    腾讯云归档存储(Cloud Archive Storage, CAS)是面向企业和个人开发者提供的低成本、高可靠且易于管理的云端离线存储服务,适用于海量、非结构化数据长时间备份,实现数据的容灾和c。归档存储采用分布式云端存储,您可以通过 RESTful API 对存储的数据进行访问。归档存储易于管理,您无需关心硬件维护及容量扩展;按实际使用量付费,为您节省额外成本。
    来自:

扫码关注云+社区

领取腾讯云代金券