自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

夏季版

知识在于积累

  • 博客(542)
  • 资源 (9)
  • 收藏
  • 关注

原创 kubernetes如何实现自定义HAP之QPS

1 背景公司本来用的是普通的基于CPU和内存的HPA扩容策略,但是运维发现效果并不是太好,所以开发这边花点时间去研究一下自定义HPA,希望达到的目的大概是这样:比如一个service下当前只有一个pod,这个pod能抗的并发是100,那么假如当前的并发变成了300,那么此时HPA就应该要能监测到这个变化,将pod扩容为3个。2 理论基础1 普罗米修斯第一种 Metrics,是宿主机的监控数据。这部分数据的提供,需要借助一个由 Prometheus 维护的Node Exporter 工具。一般来说,

2022-05-10 18:24:21 933

原创 Java提供了哪些IO方式? NIO如何实现多路复用?

Java IO 方式有很多种,基于不同的 IO 抽象模型和交互方式,可以进行简单区分。首先,传统的 java.io 包,它基于流模型实现,提供了我们最熟知的一些 IO 功能,比如 File 抽象、输入输出流等。交互方式是同步、阻塞的方式,也就是说,在读取输入流或者写入输出流时,在读、写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线性顺序。java.io 包的好处是代码比较简单、直观,缺点则是 IO 效率和扩展性存在局限性,容易成为应用性能的瓶颈。很多时候,人们也把 java.net 下面

2021-08-18 17:31:34 230

原创 如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?

Java 提供了不同层面的线程安全支持。在传统集合框架内部,除了 Hashtable 等同步容器,还提供了所谓的同步包装器(Synchronized Wrapper),我们可以调用 Collections 工具类提供的包装方法,来获取一个同步的包装容器(如 Collections.synchronizedMap),但是它们都是利用非常粗粒度的同步方式,在高并发情况下,性能比较低下。另外,更加普遍的选择是利用并发包提供的线程安全容器类,它提供了:各种并发容器,比如 ConcurrentHashMap、Co

2021-08-18 17:30:37 266

原创 对比Hashtable、HashMap、TreeMap有什么不同?

Hashtable、HashMap、TreeMap 都是最常见的一些 Map 实现,是以键值对的形式存储和操作数据的容器类型。Hashtable 是早期 Java 类库提供的一个哈希表实现,本身是同步的,不支持 null 键和值,由于同步导致的性能开销,所以已经很少被推荐使用。HashMap 是应用更加广泛的哈希表实现,行为上大致上与 HashTable 一致,主要区别在于 HashMap 不是同步的,支持 null 键和值等。通常情况下,HashMap 进行 put 或者 get 操作,可以达到常数时

2021-08-18 17:29:08 179

原创 对比Vector、ArrayList、LinkedList有何区别?

这三者都是实现集合框架中的 List,也就是所谓的有序集合,因此具体功能也比较近似,比如都提供按照位置进行定位、添加或者删除的操作,都提供迭代器以遍历其内容等。但因为具体的设计区别,在行为、性能、线程安全等方面,表现又有很大不同。Vector 是 Java 早期提供的线程安全的动态数组,如果不需要线程安全,并不建议选择,毕竟同步是有额外开销的。Vector 内部是使用对象数组来保存数据,可以根据需要自动的增加容量,当数组已满时,会创建新的数组,并拷贝原有数组数据。ArrayList 是应用更加广泛的动态

2021-08-18 17:28:25 104

原创 int和Integer有什么区别?

int 是我们常说的整形数字,是 Java 的 8 个原始数据类型(Primitive Types,boolean、byte 、short、char、int、float、double、long)之一。Java 语言虽然号称一切都是对象,但原始数据类型是例外。Integer 是 int 对应的包装类,它有一个 int 类型的字段存储数据,并且提供了基本操作,比如数学运算、int 和字符串之间转换等。在 Java 5 中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java 可以根据上下文

2021-08-18 17:26:39 349

原创 谈谈 Java 反射机制,动态代理是基于什么原理?

反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了上面提到的反射机制。还有其他的实现方式,比

2021-08-18 17:25:27 149

原创 String、StringBuffer、StringBuilder有什么区别?

String 是 Java 语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是典型的 Immutable 类,被声明成为 final class,所有属性也都是 final 的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String 对象。由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。StringBuffer 是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,我们可以用 append 或者 add 方法,把字符串添加到已有序列的末尾或者指定

2021-08-18 17:21:45 100

原创 强引用、软引用、弱引用、幻象引用有什么区别?

不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响。所谓强引用(“Strong” Reference),就是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为 null,就是可以被垃圾收集的了,当然具体回收时机还是要看垃圾收集策略。软引用(SoftReference),是一种相对强引用弱化一些的引用,可以让对象豁免一

2021-08-18 17:20:08 100

原创 谈谈 final、finally、 finalize 有什么不同?

final 可以用来修饰类、方法、变量,分别有不同的意义,final 修饰的 class 代表不可以继承扩展,final 的变量是不可以修改的,而 final 的方法也是不可以重写的(override)。finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。finalize 是基础类 java.lang.Object 的一个方法,它的设计目的是保证对

2021-08-18 16:59:27 100

原创 Exception和Error的区别

Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、.

2021-08-18 16:58:09 418

原创 17分析veth pair设备创建后无法互ping的问题

1、创建了一个veth pair设备,且设置ip地址ip link add veth0 type veth peer name veth1ip addr add 192.168.1.101/24 dev veth0ip addr add 192.168.1.102/24 dev veth1ip link set veth0 up ip link set veth1 up2、创建完成后此时两张网卡情况如下所示:3、但是此时通过veth0这张网卡去ping veth1,发现不通 ping -

2021-08-11 11:47:18 997 5

原创 16 如何找到docker中容器网卡外联的veth pair的另一张网卡

1、背景知识比如docker或者kubernetes的calico网络插件,其实都使用到了veth pair设备,即容器里面的网卡是veth pair的一端,宿主机上的某张网卡是veth pair的另一端,那么假如我想知道到底对应的是宿主机上的哪张网卡有什么办法吗?有的,方法好几种,介绍最方便的一种2、步骤:a、进入到容器,执行如下命令:ip link show eth0b、注意这里输出的161: eth0@if162,其中161是eth0接口的index,162是和它成对的veth的index

2021-08-11 10:02:41 813

原创 15 Service与Ingress

这种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的 Ingress 服务。所以,Ingress 的功能其实很容易理解:所谓 Ingress,就是 Service 的“Service”。这种本质,其实就是请求先发送到了ingress,然后ingress帮你根据规则进行转发。在实际的使用中,你只需要从社区里选择一个具体的 Ingress Controller,把它部署在 Kubernetes 集群里即可。然后,这个 Ingress Controller 会

2021-08-10 13:46:56 307

原创 14 kubernetes如何从外界连通Service

1、方式一: nodePort方式2、方式二:公有云上的 Kubernetes 服务。这时候,你可以指定一个 LoadBalancer 类型的 Service公有云提供的 Kubernetes 服务里,都使用了一个叫作 CloudProvider 的转接层,来跟公有云本身的 API 进行对接。所以,在上述 LoadBalancer 类型的 Service 被提交后,Kubernetes 就会调用 CloudProvider 在公有云上为你创建一个负载均衡服务,并且把被代理的 Pod 的 IP 地址配置给

2021-08-10 13:39:47 162

原创 13 kubernetes中Service 与 DNS 的关系

查看当前集群中的service那么此时其他容器要访问这个service,就可以通过这个DNS来访问:portalms-server-svc.wisecloud.svc.cluster.local这其实就是一个coreDNS服务做到的,那么总得有个映射吧,这个映射在哪呢?通过查看coreDNS的服务,发现对应的deployment这里进行了一个挂载发现这里是通过configMap的方式挂载的,那么就需要查看一下这个configMapkubectl get configMap -n kube-s

2021-08-10 11:42:25 181

原创 12 kubernetes中service的实现原理

1、说明Kubernetes 之所以需要 Service,一方面是因为 Pod 的 IP 不是固定的,另一方面则是因为一组 Pod 实例之间总会有负载均衡的需求2、service原理一之“kube-proxy组件+iptables规则”kube-proxy 通过 iptables 处理 Service 的过程,其实需要在宿主机上设置相当多的 iptables 规则。而且,kube-proxy 还需要在控制循环里不断地刷新这些规则来确保它们始终是正确的。不难想到,当你的宿主机上有大量 Pod 的时候,

2021-08-10 11:08:36 271

原创 11理解kubernetes的calico网络插件

1、Flannerl的host-gw模式:假设现在node1上的容器Infra-container-1要访问node2上的Infra-container-2,其中节点1的网段是10.168.0.2/24,节点2的网段是10.168.0.3/24,这也就意味着节点之间是可以通过eth0网卡进行通信的。且节点1的cni0的网段是10.244.0.1/24,节点2的cni0的网段是10.244.1.1/24。此时会在宿主机上创建这些路由规则:(比如节点1)这意味着目标地址是10.244.1.0/24这个

2021-08-10 10:31:11 216

原创 10 docker容器网络原理

1、什么是网络栈网络栈包括了网卡、回环设备、路由表和iptables规则2、容器声明直接使用宿主机的网络栈使用如下命令来启动一个容器,声明使用宿主机的网络栈docker run -d --net=host --name nginx-host nginx容器启动后如下所示:查看一下宿主机上的80端口,发现80端口已经被占用了,而刚才在启动nginx之前该端口是没有被占用的。访问一下该服务,确实能访问通。此时说明了,容器是可以直接使用宿主机的网络的。2、容器如何拥有自己的网络栈网桥(b

2021-08-09 10:18:15 161

原创 9 如何将网元服务制作成一个chart并上传到私有仓库

1、首先先给出一个chart模板吧csdn不支持文件上传,自动去获取吧:文档:3 portalms的chart模板.note链接:http://note.youdao.com/noteshare?id=6bdec69d7ea7006a16b89ba18ccefc4a&sub=1C59F7DBE76843BC8AE58B73EB2CDFF22、接下来说一下这个chart里面的主要功能Chart.yaml文件里面的内容没有什么好说的,配置信息而已。values.yaml文件里面需要特别注意

2021-08-06 17:12:22 191

原创 kubernetes+rancher+docker+helm+harbor搭建云平台服务思路小结

1 架构介绍一下架构中的每个组件的作用吧1、Jenkins自动化工具2、gitlab存储代码3、docker镜像:相当于一个携带了运行环境的安装包容器:运行启动的镜像,就是一个容器4、harbor私有的镜像仓库,用来存储镜像。docker仓库的企业版(https://hub.docker.com/)5、k8s集群容器,就是进程;容器镜像“.exe”安装包。Kubernetes 就是操作系统!所以k8s集群可以简单理解为多个操作系统,就是用来运行容器的!只是k8s额外提供了很多其他

2021-08-06 16:57:35 833

原创 8 pod的调度

1、先回顾一下我当前k8s集群里面的所有资源:kubectl get all --all-namespaces2、为什么需要调度功能?很好理解,假如我线上有一个集群,其中一台机器的CPU和内存特别高,而另一台的性能很差,而如果只是简单的创建一个pod的话,显然这个pod是会根据一个算法随机调度到一个主机上的,但是我这个服务是一个特别耗cpu和内存的服务,我自然希望他调度到一台好点的机器上去。那么就需要定向调度了。通过noeName字段来定向调度:apiVersion: v1kind: Pod

2021-08-05 18:41:30 157

原创 7 实战云平台开发人员的流程-如何制作一个chart

1、如云平台整体架构图所示,下面这里是开发人员的流程图。接下来就来搭建一下环境。2、首先gitlab、harbor的搭建,这里就忽略掉了3、

2021-08-05 16:25:42 456 2

原创 6 pod的生命周期

1、流程图如下所示:2、初始化容器apiVersion: v1kind: Podmetadata: name: pod-initcontainer namespace: testspec: containers: - name: main-container image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 initContainers: - name:

2021-08-05 14:06:34 76

原创 5 理解k8s中的pod

1 熟悉pod的配置字段一个完整的Pod的资源清单肯定是很多的,但是我显然是记不住的,那么编写yaml文件的时候如果忘记了怎么办呢?使用如下命令:kubectl explain pod这样就能看到FIELDS里面所有可以编写的字段了,如果又不知道metadata里面的字段不清楚,那么继续使用这种格式去追踪即可:kubectl explain pod.metadata2 熟悉pod的配置1、先创建一个pod-base.yaml文件,内容如下所示:apiVersion: v1kind: Po

2021-08-05 11:07:49 1085

原创 4 分析yaml文件

1 创建命名空间首先查看一下当前的所有命名空间:kubectl get namespace使用yaml文件的方式生成一个名为test的命令空间,创建namespace-test.yaml文件,内容为:apiVersion: v1kind: Namespacemetadata: name: test执行如下命令kubectl apply -f namespace-test.yaml,创建这个namespace再次查看namespace,就发现已经创建好了2 创建podapiVe

2021-08-04 17:57:24 244

原创 3 k8s创建一个nginx试试

1 安装一个nginx服务试试1、因为我使用的是集群的default这个默认命名空间,所以先执行如下命令查看当前集群里面的所有资源:kubectl get all -n default -o wide发现这里已经有了一个service的资源,这个资源是干嘛的?执行如下命令:kubectl describe service kubernetes发现是代理到了163的6443端口,而6443端口发现是kube-apiserver这个服务的端口。猜测启动这个服务的目的是为了让其他资源能通过dns

2021-08-04 17:27:36 340

原创 2 kubernetes集群搭建与集群服务分析

1 环境说明1、内网两台服务器,192.168.1.163和192.168.1.166,计划将163作为集群的master节点,166作为集群的从节点2、两台服务器是centos 7, linux内核是3.10以上的。内存4G,cpu两核,这个是必要条件2 安装步骤1、在163服务器上执行:hostnamectl set-hostname k8s-master01 && bash2、在166服务器上执行:hostnamectl set-hostname k8s-node01 &

2021-08-04 16:48:55 291

原创 1 云平台流程图

1 流程图2 组件介绍2.1 jenkins内网环境地址:http://192.168.1.100:8080/作用:自动化2.2 gitlab内网环境地址:http://192.168.1.6:8000/作用:存储代码2.3 docker镜像:相当于一个携带了运行环境的安装包容器:运行启动的镜像,就是一个容器举例nginx说明:1、登录到192.168.1.135服务器上2、执行如下命令查看nginx镜像是否存在: docker images |grep nginx

2021-08-04 11:26:07 1390

原创 7 Kubernetes容器网络

1、容器网络linux容器能看见的网络栈,实际上被隔离在它自己的network namespace中。网络栈包含了网卡、回环设备、路由表和iptables规则。作为一个容器,可以声明直接使用宿主机的网络栈。即:但是,在大多数情况下,我们希望容器进程使用自己network namespace的网络栈。拥有自己的Ip地址和端口那么,这个被隔离的容器进程,如何和其他的network namespace里的容器进程进行交互呢?2、docker容器通信的原理linux中,能够起到虚拟交换机作用的网络设备,

2021-07-25 19:03:40 214

原创 5 Kubernetes容器持久化存储

1、PV是什么PV描述的,是持久化存储数据卷,定义的是一个持久化存储在宿主机上的目录,比如NFS的挂载目录通常情况下,PV对象是运维人员实现创建在k8s集群里待用的。如下所示2、PVCPVC描述的,则是pod所希望使用的持久化存储的属性,常由开发人员创建3、PV和PVC存在的问题比如创建pod的时候,系统里并没有合适的pv和定义的pvc,那么意味着容器想要使用的volumn不存在,那么此时pod启动就会报错。而这个时候只能运维人员去配置。而为了解决这个问题,增加了一个volumn Contro

2021-07-25 17:54:41 93

原创 4 容器编排与Kubernetes作业管理

1、为什么需要Pod容器,就是未来云计算系统中的进程,容器镜像就是这个系统中的.exe安装包,k8s就是操作系统在真正的操作系统中,进程是以进程组的方式存在的,k8s就是将进程组的概念映射到了容器技术中如果没有组的概念,这样的运维关系会非常难以处理pod是k8s里的原子调度单位,k8s的调度器,是统一按照pod而非容器的资源需求进行计算的pod的实现原理:pod只是一个逻辑概念,pod是一组共享了某些资源的容器,pod里的所有容器,共享的是同一个network namespace,并且可以声明共

2021-07-25 17:36:29 164

原创 3 k8s集群实践

1、k8s集群搭建网上方式很多,不介绍,基本步骤如下:在所有节点上安装docker和kubeadm部署k8s master部署容器网络插件部署k8s worker部署dashboard可视化插件部署容器存储插件2、k8s中的重要概念开发者第一步,是要制作容器的镜像提交镜像编写k8s的编配配置文件yaml文件通过yaml文件启动在deployment中声明volume3、k8s的几个常用命令以及含义通过配置文件创建或更新服务: kubectl apply -f 配置文

2021-07-25 16:21:30 88

原创 2 容器技术概念入门篇

1、到底什么是容器容器其实是一种沙盒技术,能够像一个集装箱一样,把你的应用装起来的技术,这样应用与应用之间,就因为有了便捷而不至于互相干扰。2、容器是怎么实现的容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个边界。对于docker来说,cgroups技术是用来制造约束的主要手段,而namespace技术则是用来修改进程视图的主要方法3、linux的namespace机制linux系统中创建线程的系统调用时clone(),而这里面可以指定参数CLONE_NEWPID参数

2021-07-25 16:06:16 188 2

原创 1 容器技术的背景

1、背景从过去以物理机和虚拟机为主体的开发运维环境,向以容器为核心的基础设施的转变过程,并不是一次温和的改革,而是涵盖了对网络、存储、调度、操作系统、分布式原理等各方面的容器化理解和改造。2、什么是paasplatform as a service,指的是平台即服务3、为什么docker可以脱颖而出docker项目给paas世界带来的降维打击,其实是提供了中非常便利的打包机制,这种机制直接打包了应用运行所需要的的整个操作系统,从而保证了本地环境和云端环境的高度一致,避免用户通过试错来匹配不同运行环

2021-07-25 14:42:35 382

原创 读码农翻身之用来维护本线程变量的ThreadLocal

1、为什么需要ThreadLocal?来看这样一个实例,在某个类中,创建了一个Context的对象,其中设置了一个trackerID,然后再调用了其他的java类,然后最终需要使用到ctx的这个tranckerID要怎么办?有人想,直接把Context对象一层层传递下去,这样到时候就可以用到了但是这样的缺点,就是太麻烦,有时候改动会很大。此时又有人认为可以把set/get TrackerID的方法修改为static静态方法。但是这样多线程并发的时候有可能出问题。(因为线程1调用了set,然后线

2020-05-22 15:12:17 210

原创 读码农翻身之Java虚拟机的堆

回顾一下java内存区域划分:1、Heap中主要保存对象2、垃圾回收:java程序员只需要将对象给new出来,扔到heap中,但是从来不把它delete掉,所以需要有垃圾回收机制来删掉这些对象。而这其中也涉及到一些算法如 可达性分析算法:橙色的对象都是不可达对象,可以回收3、Heap的详解可以把Heap想象成一大片空间,为了方便管理,把heap划分为多个区域,然后把那些java对象在其中搬来搬去。规定:新创建出来的对象,是保存在新生代中的,如果新生代住不下了,就进行垃圾回收(Minor G

2020-05-22 14:42:32 178

原创 读码农翻身之ASM

1、什么是ASMASM可以动态的修改已经编译过的class,还可以动态的生成新的java class。(动态:表示完全在运行时,在内存中完成的)之所以叫ASM,创造者在创造的时候,为了起名大费周章,后来突然想到C语言中的__asm__这个关键字,可以允许在C语言中写点汇编。就把ASM这个关键字挪用了。2、为什么需要ASM能对现有的class进行修改3、怎么实现动态修改类?ASM的核心主要是三个类,ClassReader、ClassWriter、ClassVisitor,用这三个类就可以去解析一个

2020-05-22 14:02:53 181

原创 读码农翻身之JMS

1、为什么需要JMS?JMS即Java消息服务(Java Message Service),随着各种消息队列的出现,定义了各式各样的API,导致互不兼容,学习成本高。使用不方便。2、定义标准消息生产者、消息消费者、生产者提供发送消息的方法,消费者提供接收消息的方法。不管是生产者向队列发送消息,还是消费者去接收消息,其实都是在和消息队列进行交互。所以引入一个会话(session)的概念出来。Session可以创建消息,同时生产者和消费者也应该由Session来创建,一个发送接收消息肯定是在一个会话里

2020-05-22 11:27:34 203

原创 读码农翻身之消息队列

1、为什么需要消息队列?假如有一个购物系统,逻辑上分为订单系统和库存系统,订单来了以后,先在订单系统中存下来,然后通知库存系统发货。此时这个购物系统是部署在一台服务器上的。但是当用户量越来越多的时候,服务器慢慢的快扛不住了。慢慢的进行了拆分的操作,即订单系统和库存系统,分别在两台服务器上进行保存,也就是现在订单系统如果要通知库存系统,那么就需要从原来的java方法调用,换成了http调用。那么这个时候又可能出现问题,因为现在有http请求,那么就意味着http请求有可能是不通的,那么如果失败后,

2020-05-22 11:08:49 189

redis自动化安装

支持redis单机,主从部署,文档齐全,yijia

2017-08-16

postgresql数据库自动化单机主从部署-吴永胡

postgresql数据库自动化单机主从部署

2017-08-09

postgresql数据库手动安装以及主从配置

postgresql数据库手动安装以及主从配置

2017-08-07

IT经典资料分享-含高清下载链接(第一版).pdf

IT经典资料分享-含高清下载链接(第一版).pdf

2017-07-07

SQLAlchemy详细教程

sqlAlchemy教程

2017-07-07

java项目中cas和authcenter的集成

CasClientUtil.java

2017-06-26

redis操作工具类

封装了所有对redis操作的工具

2017-04-26

nodejs开发微信公众号第三天代码 可以实现推送消息

nodejs开发微信公众号

2016-12-13

nodejs开发微信公众号第二天代码

慕课网开发微信第二天源代码

2016-12-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除