关于alibaba:Spring-Cloud-Alibaba-微服务架构实战

download:Spring Cloud / Alibaba 微服务架构实战/** 图片搜寻为进步搜寻的精确度,举荐应用配套工具截图 http://www.xnx3.com/software/... */public static void imageSearch(){ Robot robot = new Robot();robot.setSourcePath(RobotDemo.class); //设置此处是为了让程序能主动找到要搜寻的图片文件。图片文件在以后类下的res文件夹内 //在以后屏幕上搜寻search.png图片,看起是否存在List<CoordBean> list1 = robot.imageSearch("search.png", Robot.SIM_ACCURATE);System.out.println(list1.size()>0? "搜寻到了"+list1.size()+"个指标":"没搜寻到");if(list1.size()>0){ for (int i = 0; i < list1.size(); i++) { CoordBean coord = list1.get(i); System.out.println("搜寻到的第"+(i+1)+"个坐标:x:"+coord.getX()+",y:"+coord.getY()); }} //在屏幕上指定的区域:左上方x100,y100, 右下方x300,y300的范畴内搜寻多个图像List<CoordBean> list2 = robot.imageSearch(100, 100, 300, 300, "search.png|L.png", Robot.SIM_BLUR_VERY);System.out.println(list2.size()>0? "搜寻到了"+list2.size()+"个指标":"没搜寻到");if(list2.size()>0){ for (int i = 0; i < list2.size(); i++) { CoordBean coord = list2.get(i); System.out.println("搜寻到的第"+(i+1)+"个坐标:x:"+coord.getX()+",y:"+coord.getY()); }}}

August 18, 2021 · 1 min · jiezi

关于alibaba:Spring-Cloud-Alibaba-微服务架构实战

downloada:Spring Cloud / Alibaba 微服务架构实战import org.apache.commons.lang3.StringUtils;import org.apache.http.HttpStatus;import org.jsoup.Connection;import org.jsoup.Jsoup;import org.jsoup.Connection.Response;import javax.net.ssl.*;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.HashMap;import java.util.Map;/** Created by Jane on 2015/9/10. */public class JsoupHttpRequest { public static void main(String[] args) throws Exception { String url = "http://localhost:8080/fileUpload"; File file = new File("/opt/fileUpload/index.jpg"); String fileRquestParam = "file"; Map<String, String> dataMap = new HashMap<String, String>(); dataMap.put("userName", "admin"); dataMap.put("md5", "12cd76nskju98zud7fda0f6c9wa54"); Response response = doPostFileRequest(url, dataMap, file, fileRquestParam); System.out.println(response.statusMessage());}/** * @param url 请求的Url * @param paramMap 参数 * @param file 文件 * @param fileRequestParam form表单对应的文件name属性名 * @return * @throws Exception */public static Response doPostFileRequest(String url, Map<String, String> paramMap, File file, String fileRequestParam) throws Exception { if (StringUtils.isBlank(url)) { throw new Exception("The request URL is blank."); } // Https请求 if (StringUtils.startsWith(url, "https")) { trustEveryone(); } Connection connection = Jsoup.connect(url); connection.method(Connection.Method.POST); connection.timeout(12000); connection.header("Content-Type", "multipart/form-data"); connection.ignoreHttpErrors(true); connection.ignoreContentType(true); if (paramMap != null && !paramMap.isEmpty()) { connection.data(paramMap); } try { FileInputStream fis = new FileInputStream(file); connection.data(fileRequestParam, file.getName(), fis); } catch (FileNotFoundException e) { e.printStackTrace(); } try { Response response = connection.execute(); if (response.statusCode() != HttpStatus.SC_OK) { throw new Exception("http请求响应码:" + response.statusCode() + ""); } return response; } catch (IOException e) { e.printStackTrace(); } return null;}/** * 解决Https请求,返回404谬误 */private static void trustEveryone() { try { HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, new X509TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); }}

August 17, 2021 · 2 min · jiezi

Spring-Cloud-Alibaba-Nacos-Config-实战

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置 一、安装 Nacos1、下载 Nacos最新稳定版下载:https://github.com/alibaba/nacos/releases 2、启动 Nacos启动 Nacos (单机模式) sh startup.sh -m standalone关闭 Nacos sh shutdown.sh二、配置 Nacos1、打开 Nacos默认地址:http://127.0.0.1:8848/nacos/#/login 默认账号:账号密码相同,都为nacos 2、添加配置配置数据: Data ID: nacos-dev.propertiesGroup : DEFAULT_GROUP配置格式: Properties配置内容: useLocalCache=true Data ID 的格式说明: ${prefix}-${spring.profile.active}.${file-extension}prefix: 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置 spring.profile.active: 即为当前环境对应的 profile, 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension} file-exetension: 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型 ...

October 17, 2019 · 1 min · jiezi

基于阿里egg框架搭建博客2HelloWorld

相关文章基于阿里egg框架搭建博客(1)——开发准备基于阿里egg框架搭建博客(2)——Hello World基于阿里egg框架搭建博客(3)——注册与登录基于阿里egg框架搭建博客(4)——权限控制基于阿里egg框架搭建博客(5)——置顶导航条基于阿里egg框架搭建博客(6)——浏览、发表文章基于阿里egg框架搭建博客(7)——编辑文章 githttps://github.com/ZzzSimon/e...喜欢就点个赞吧! 正文这是必备的Hello World章节,本章节将不使用脚手架,逐步创建一个hello world web应用。 初始化项目先来初始化下目录结构: $ mkdir egg-hello-world$ cd egg-hello-world$ npm init$ npm i egg --save$ npm i egg-bin --save-dev执行完成后如下图所示:除了下载的node模块以外什么都没有,不要着急,我们接下来会一点点创建。 添加 npm scripts 到 package.json: { "name": "egg-example", "scripts": { "dev": "egg-bin dev" }}编写Controller上一节我们知道,controller是需要放在app/controller/目录下的,所以我创建helloWorld.js文件: // app/controller/home.jsconst Controller = require('egg').Controller;class HelloWorldController extends Controller { async index() { this.ctx.body = 'Hello World'; }}module.exports = HelloWorldController;编写路由规则egg将路由交由app/router.js管理,于是我们在app/目录下创建router.js文件: // app/router.jsmodule.exports = app => { const { router, controller } = app; router.get('/', controller.helloWorld.index);};配置文件最后加上一个配置config/config.default.js文件:注意:config与app为同级目录! ...

October 14, 2019 · 1 min · jiezi

Alibaba Sentinel(1):快速上手

Alibaba Sentinel 是一个灵活的系统负载控制框架,通过控制接口和方法的调用来保证系统负载不会过大,维持正常响应速度。该项目的地址是 https://github.com/alibaba/Se… 。但是阿里的文档一贯看起来一头雾水,所以本文介绍如何用一个最简单的项目来上手。如果你熟悉 Spring Boot,那么几分钟就可以搞定。1、创建一个 Maven 项目首先创建一个空的 Maven 项目,加上 Spring Boot 的依赖。pom.xml 看起来是下面的样子,你可以直接拿来用:<?xml version=“1.0” encoding=“UTF-8”?><project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>sentinel-test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement></project>这里没有将 Spring Boot 作为 parent 项目,而是使用 <dependencyManagement>,但效果是一样的。2、添加依赖关系在 pom.xml 中,首先添加 Spring Boot 依赖:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId></dependency>然后添加 Sentinel。在这个例子当中,我们将用 注解 来实现负载控制,所以添加 sentinel-annotation-aspectj 依赖:<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-annotation-aspectj</artifactId> <version>1.5.1</version></dependency>添加了这两个依赖就 OK 了。3、启动类Spring Boot 项目需要一个 main() 方法来启动,我们命名这个类为 com.demo.SentinelTestApplication,其内容如下:@SpringBootApplicationpublic class SentinelTestApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SentinelTestApplication.class, args); }}目前这个类还没有具体的内容,但我们应该先运行一下,确保前面做的事情没有出错,然后再添加内容。4、需要进行访问控制的服务 DemoService我们在 com.demo 包下创建一个名为 DemoService 的类,这个类包含一个需要做访问控制的 call() 方法:@Servicepublic class DemoService { private int counter; @SentinelResource(value = “DemoService.call”, blockHandler = “callBlocked”) public void call() { System.out.println(“Hello (” + ++counter + “)”); } public void callBlocked(BlockException ex) { System.err.println(“Blocked (” + ++counter + “) : " + ex.toString()); }}所谓访问控制就是当某个方法调用过于频繁时,拒绝掉一部分调用。什么才叫过于频繁,我们可以通过自定义控制规则的方式来告诉 Sentinel。定义控制规则的部分放在后面介绍,我们现在先关注业务本身,也就是 DemoService 类。这个类包含两个方法,其中 call() 方法是主角,正常的业务会调用这个方法;而 callBlocked() 则会在 call() 方法被拒绝掉时调用。call() 方法上面的 @SentinelResource 注解标明了该方法是需要进行访问控制的。Sentinel 将需要进行访问控制的方法都称作资源。这个注解有两个属性,value 属性表示该资源的名称,我们通过名称为不同的资源制定不同的控制规则。blockHandler 属性表示方法被拒绝时应该调用哪个替代方法,这个替代方法必须在同一个类当中,且参数列表要在原方法参数列表的基础上再添加一个 BlockException 类型的参数。5、编写控制规则Sentinel 将控制规则包装为 com.alibaba.csp.sentinel.slots.block.flow.FlowRule 类。它包含下面几个属性:resource : 该规则针对哪个资源;grade : 从哪个方面进行度量,如该方法的每秒调用次数,或同时调用该方法的线程数等等。count : 度量阈值。超过这个阈值则会拒绝调用该方法。strategy : 多个规则之间的搭配策略,具体参考这里。下面我们在 SentinelTestApplication 类里面添加一个创建规则的方法,同时在 main() 方法里面初始化它: private static void initRules() throws Exception { FlowRule rule1 = new FlowRule(); rule1.setResource(“DemoService.call”); rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setCount(5); // 每秒调用最大次数为 5 次 List<FlowRule> rules = new ArrayList<>(); rules.add(rule1); // 将控制规则载入到 Sentinel com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager.loadRules(rules); } public static void main(String[] args) throws Exception { initRules(); // Sentinel 载入规则不一定非要在 Spring 初始化之前,在这之后也可以。 SpringApplication.run(SentinelTestApplication.class, args); }这样 Sentinel 的规则就设置完毕。6、启用 Sentinel 注解的 AOP 拦截Spring 提供 AOP 机制来实现方法调用的拦截,这是 Sentinel 实现控制规则的原理。Sentinel 提供 com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect 类,我们要在 Spring 容器中加入这个 bean 才能让 @SentinelResource 注解起作用。我们需要在 SentinelTestApplication 类里面添加下面的代码: @Bean public SentinelResourceAspect sentinelResourceAspect() { return new SentinelResourceAspect(); }当然,在实际项目里面这一步可以放到自动配置当中。7、测试控制规则最后我们写一个方法来测试控制规则是否起作用,同样是在 SentinelTestApplication 类里面: @Autowired private DemoService demoService; @PostConstruct public void run() { for (int i = 0; i < 10; i++) { demoService.call(); } }实际运行 main() 方法时,你将会看到这样的输出:Hello (1)Hello (2)Hello (3)Hello (4)Hello (5)Blocked (6) : com.alibaba.csp.sentinel.slots.block.flow.FlowExceptionBlocked (7) : com.alibaba.csp.sentinel.slots.block.flow.FlowExceptionBlocked (8) : com.alibaba.csp.sentinel.slots.block.flow.FlowExceptionBlocked (9) : com.alibaba.csp.sentinel.slots.block.flow.FlowExceptionBlocked (10) : com.alibaba.csp.sentinel.slots.block.flow.FlowException通过这个例子,你应该大概了解 Sentinel 运作的机制了。在这个基础上,Sentinel 还能实现控制规则的实时修改、远程配置、状态监控等等,它是个非常强大的框架。 ...

April 10, 2019 · 2 min · jiezi

Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注。虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭借阿里中间件团队的背景,还是得到不少团队的支持;同时,由于Spring Cloud Alibaba中的几项主要功能都直指Netflix OSS中的重要组件,而后者最近频繁宣布各组件不在更新新特性,这使得Spring Cloud Alibaba关注度不断飙升,不少开发者或团队也开始小范围试水。笔者对此也进行了一段时间的调研与试水,接下来计划以《Spring Cloud Alibaba基础教程》为主题,为大家完成一套快速入门的免费内容,以支持开源社区的发展! ^_^更多关于Spring Cloud Alibaba的介绍可见:《Spring Cloud 加盟重量级成员Spring Cloud Alibaba,打造更符合中国国情的微服务体系》什么是NacosNacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。在接下里的教程中,将使用Nacos作为微服务架构中的注册中心(替代:eurekba、consul等传统方案)以及配置中心(spring cloud config)来使用。安装Nacos下载地址:https://github.com/alibaba/na…本文版本:0.7.0下载完成之后,解压。根据不同平台,执行不同命令,启动单机版Nacos服务:Linux/Unix/Mac:sh startup.sh -m standaloneWindows:cmd startup.cmd -m standalonestartup.sh脚本位于Nacos解压后的bin目录下。这里主要介绍Spring Cloud与Nacos的集成使用,对于Nacos的高级配置,后续再补充。所以,持续关注我的博客或者公众号吧!启动完成之后,访问:http://127.0.0.1:8848/nacos/,可以进入Nacos的服务管理页面,具体如下;构建应用接入Nacos注册中心在完成了Nacos服务的安装和启动之后,下面我们就可以编写两个应用(服务提供者与服务消费者)来验证服务的注册与发现了。服务提供者第一步:创建一个Spring Boot应用,可以命名为:alibaba-nacos-discovery-server。如果您还不会或者不了解Spring Boot应用,建议先学习《Spring Boot基础教程》。第二步:编辑pom.xml,加入必要的依赖配置,比如:<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!– lookup parent from repository –></parent><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.2.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> <optional>true</optional> </dependency></dependencies>上述内容主要三部分:parent:定义spring boot的版本dependencyManagement:spring cloud的版本以及spring cloud alibaba的版本,由于spring cloud alibaba还未纳入spring cloud的主版本管理中,所以需要自己加入dependencies:当前应用要使用的依赖内容。这里主要新加入了Nacos的服务注册与发现模块:spring-cloud-starter-alibaba-nacos-discovery。由于在dependencyManagement中已经引入了版本,所以这里就不用指定具体版本了。第三步:创建应用主类,并实现一个HTTP接口:@EnableDiscoveryClient@SpringBootApplicationpublic class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @Slf4j @RestController static class TestController { @GetMapping("/hello") public String hello(@RequestParam String name) { log.info(“invoked name = " + name); return “hello " + name; } }}内容非常简单,@SpringBootApplication定义是个Spring Boot应用;@EnableDiscoveryClient开启Spring Cloud的服务注册与发现,由于这里引入了spring-cloud-starter-alibaba-nacos-discovery模块,所以Spring Cloud Common中定义的那些与服务治理相关的接口将使用Nacos的实现。这点不论我们使用Eureka、Consul还是其他Spring Cloud整合的注册中心都一样,这也是Spring Cloud做了封装的好处所在,如果对Eureka、Consul这些注册中心的整合还不熟悉的可以看看以前的这篇:Spring Cloud构建微服务架构:服务注册与发现(Eureka、Consul)。第四步:配置服务名称和Nacos地址spring.application.name=alibaba-nacos-discovery-serverserver.port=8001spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848第五步:启动上面创建的应用。可以在启动时候增加-Dserver.port=8001的形式在本机的不同端口上启动多个实例。在应用启动好之后,我们可以在控制台或日志中看到如下内容,代表已经注册成功:INFO 10476 — [ main] o.s.c.a.n.registry.NacosServiceRegistry : nacos registry, alibaba-nacos-discovery-server 10.123.18.216:8001 register finished在启动都ok之后,我们可以访问Nacos的管理页面http://127.0.0.1:8848/nacos/来查看服务列表,此时可以看到如下内容:这里会显示当前注册的所有服务,以及每个服务的集群数目、实例数、健康实例数。点击详情,我们还能看到每个服务具体的实例信息,如下图所示:服务消费者接下来,实现一个应用来消费上面已经注册到Nacos的服务。第一步:创建一个Spring Boot应用,命名为:alibaba-nacos-discovery-client-common。第二步:编辑pom.xml中的依赖内容,与上面服务提供者的一样即可。第三步:创建应用主类,并实现一个HTTP接口,在该接口中调用服务提供方的接口。@EnableDiscoveryClient@SpringBootApplicationpublic class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @Slf4j @RestController static class TestController { @Autowired LoadBalancerClient loadBalancerClient; @GetMapping("/test”) public String test() { // 通过spring cloud common中的负载均衡接口选取服务提供节点实现接口调用 ServiceInstance serviceInstance = loadBalancerClient.choose(“alibaba-nacos-discovery-server”); String url = serviceInstance.getUri() + “/hello?name=” + “didi”; RestTemplate restTemplate = new RestTemplate(); String result = restTemplate.getForObject(url, String.class); return “Invoke : " + url + “, return : " + result; } }}这里使用了Spring Cloud Common中的LoadBalancerClient接口来挑选服务实例信息。然后从挑选出的实例信息中获取可访问的URI,拼接上服务提供方的接口规则来发起调用。第四步:配置服务名称和Nacos地址,让服务消费者可以发现上面已经注册到Nacos的服务。spring.application.name=alibaba-nacos-discovery-client-commonserver.port=9000spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848第五步:启动服务消费者,然后通过curl或者postman等工具发起访问,下面以curl为例:$ curl localhost:9000/testInvoke : http://10.123.18.216:8001/hello?name=didi, return : hello didi$ curl localhost:9000/testInvoke : http://10.123.18.216:8002/hello?name=didi, return : hello didi可以看到,两次不同请求的时候,真正实际调用的服务提供者实例是不同的,也就是说,通过LoadBalancerClient接口在获取服务实例的时候,已经实现了对服务提供方实例的负载均衡。但是很明显,这样的实现还是比较繁琐,预告下后面的几篇,关于服务消费的几种不同姿势。参考资料Nacos官方文档Nacos源码分析代码示例本文示例读者可以通过查看下面仓库的中的alibaba-nacos-discovery-server和alibaba-nacos-discovery-client-common项目:GithubGitee如果您对这些感兴趣,欢迎star、follow、收藏、转发给予支持!以下专题教程也许您会有兴趣Spring Boot基础教程Spring Cloud基础教程 ...

January 16, 2019 · 2 min · jiezi

Graves of the Internet - 互联网坟墓

Graves of the Internet - 互联网坟墓互联网公司逝去产品列表以此祭奠那些夕阳下的奔跑,祭奠那些逝去的青春演示地址点击 这里 https://myvin.github.io/gravesoftheinternet 体验。演示截图起因前两天偶然看到了一个项目 killedbygoogle,上面收录了淘汰的和正在死亡线上的 Google 产品/服务/应用,目前总共收录了 146 款,并且贴心地为每一款产品/服务/应用搭建了一个墓碑,墓碑上列出了产品/服务/应用的名称、上线时间、下线时间、简介和详情的维基百科链接。正好闲来无事,便随手 Google 了 BAT 淘汰的产品/服务/应用,有不少知道的,也有不少不知道的,比如有百度下吧、百度国学、百度有啊、淘江湖,也有曾让你不停抖腿的天天动听,跑过来让你充值的超级QQ,某个夜里挂机 download 资源的 QQ旋风巴拉巴拉。随着这些产品逝去的,有唏嘘,有岁月,有青春,也有大把大把散发着铜臭味的金钱…整理结果于是就整理了下 BAT 三家互联网公司已经逝去或正在逝去的产品(不包括游戏类应用)。具体可点击 这里 查看。目前整理出的 产品/服务/应用 如下:Baidu百度 mall百度 VIP百度未来商店百度医生百度直达号百度外卖百度游戏百度相册百度云 OS百度新知百伯百度说吧乐酷天百度彩票百度有啊baidu.jp 搜索业务百度空间百度国学百度下吧Alibaba智能测肤支付宝生活圈(校园日记、白领日记)支付宝借条天猫宝阿里云引擎 ACE基金淘宝店淘字号来往淘点点快的打车淘宝指数阿里旺旺国际版淘日本淘江湖阿里软件天天动听口碑网雅虎中国云手机助手阿里云博客Tencent腾讯OS(TOS)腾讯微视腾讯Q+腾讯微视腾讯微博QT语音(QQTalk)QQ影像WEB QQ朋友网QQ家园QQ旋风QQ滔滔超级QQ搜搜(SOSO)拍拍网腾讯TMTT浏览器QQ聊天室QQ日历YES平台EOF才疏学浅,难免有错,恳请指正。点击 这里 勘误。

December 23, 2018 · 1 min · jiezi