1、为什么需要dubbo?(为了解决什么问题?)

架构演变

1 单一应用架构

2 应用和数据库单独部署

3 应用和数据库集群部署

4 数据库压力变大,读写分离

5 使用缓存技术加快速度

6 数据库分库分表

7 应用分为不同的类型拆分

应用之间的关系已经十分复杂,产生了以下问题:

  • 当服务越来越多,服务 URL 配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
  • 服务间依赖关系复杂,应用的启动顺序复杂、应用的架构关系复杂
  • 服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?

2、Dubbo是什么?(dubbo技术架构)

节点角色:

节点

角色说明

Provider

暴露服务的服务提供方

Consumer

调用远程服务的服务消费方

Registry

服务注册与发现的注册中心

Monitor

统计服务的调用次数和调用时间的监控中心

Container

服务运行容器

Dubbo架构简单来说其实是生产者-消费者模型。进一步在这种模型上,加上了注册中心和监控中心,用于管理提供方提供的url,以及管理整个过程。

发布订阅过程:

  • 启动容器,加载,运行服务提供者
  • 服务提供者在启动时,在注册中心发布注册自己提供的服务
  • 服务消费者在启动时,在注册中心订阅自己所需的服务

如果考虑失败或变更的情况,就需要考虑下面的过程。

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

3、Dubbo如何使用?

3.1 定义服务提供者

新建provider提供者模块,定义如下接口:

/**

* xml方式服务提供者接口

*/

public interface ProviderService {

String SayHello(String word);

}

实现类

/**

* xml方式服务提供者实现类

*/

public class ProviderServiceImpl implements ProviderService{

public String SayHello(String word) {

return word;

}

}

3.2 服务暴露

导入maven依赖

<?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.test</groupId>

<artifactId>dubbo-provider</artifactId>

<version>1.0-SNAPSHOT</version>

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>3.8.1</version>

<scope>test</scope>

</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>dubbo</artifactId>

<version>2.6.6</version>

</dependency>

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

<version>3.4.10</version>

</dependency>

<dependency>

<groupId>com.101tec</groupId>

<artifactId>zkclient</artifactId>

<version>0.5</version>

</dependency>

<dependency>

<groupId>io.netty</groupId>

<artifactId>netty-all</artifactId>

<version>4.1.32.Final</version>

</dependency>

<dependency>

<groupId>org.apache.curator</groupId>

<artifactId>curator-framework</artifactId>

<version>2.8.0</version>

</dependency>

<dependency>

<groupId>org.apache.curator</groupId>

<artifactId>curator-recipes</artifactId>

<version>2.8.0</version>

</dependency>

</dependencies>

</project>

进行服务暴露:暴露接口(xml 配置方法)

首先,在项目 resource 目录下创建 META-INF.spring 包,然后再创建 provider.xml 文件,

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

<dubbo:application name="provider" owner="cp">

<dubbo:parameter key="qos.enable" value="true"/>

<dubbo:parameter key="qos.accept.foreign.ip" value="false"/>

<dubbo:parameter key="qos.port" value="55555"/>

</dubbo:application>

<dubbo:monitor protocol="registry"/>

<!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

<!--<dubbo:registry address="N/A"/>-->

<dubbo:registry address="N/A" />

<!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->

<dubbo:protocol name="dubbo" port="20880"/>

<!--服务发布的配置,需要暴露的服务接口-->

<dubbo:service

interface="com.dubbo.provider.service.ProviderService"

ref="providerService"/>

<!--Bean bean定义-->

<bean id="providerService" class="com.dubbo.provider.service.ProviderServiceImpl"/>

</beans>

发布接口:通过 ClassPathXmlApplicationContext 拿到我们刚刚配置好的 xml ,然后调用 context.start() 方法启动

package com.dubbo.provider;

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ProtocolConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.ServiceConfig;

import com.alibaba.dubbo.container.Main;

import com.dubbo.provider.service.ProviderService;

import com.dubbo.provider.service.ProviderServiceImpl;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**

* xml方式启动

*

*/

public class App

{

public static void main( String[] args ) throws IOException {

//加载xml配置文件启动

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");

context.start();

System.in.read(); // 按任意键退出

}

}

3.2 定义消费消费者

新建消费者consumer模块,先通过点对点方式:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

<dubbo:application name="consumer" owner="cp"/>

<!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

<!--点对点的方式-->

<dubbo:registry address="N/A" />

<!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>-->

<!--生成一个远程服务的调用代理-->

<!--点对点方式-->

<dubbo:reference id="providerService"

interface="com.dubbo.provider.service.ProviderService"

url="dubbo://localhost:20880/com.dubbo.provider.service.ProviderService"/>

<!--<dubbo:reference id="providerService"

interface="com.dubbo.provider.service.ProviderService"/>-->

</beans>

导入maven依赖(同服务端类似)

<?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.test</groupId>

<artifactId>dubbo-consumer</artifactId>

<version>1.0-SNAPSHOT</version>

<dependencies>

<dependency>

<groupId>com.test</groupId>

<artifactId>dubbo-provider</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>3.8.1</version>

<scope>test</scope>

</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>dubbo</artifactId>

<version>2.6.6</version>

</dependency>

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

<version>3.4.10</version>

</dependency>

<dependency>

<groupId>com.101tec</groupId>

<artifactId>zkclient</artifactId>

<version>0.5</version>

</dependency>

<dependency>

<groupId>io.netty</groupId>

<artifactId>netty-all</artifactId>

<version>4.1.32.Final</version>

</dependency>

<dependency>

<groupId>org.apache.curator</groupId>

<artifactId>curator-framework</artifactId>

<version>2.8.0</version>

</dependency>

<dependency>

<groupId>org.apache.curator</groupId>

<artifactId>curator-recipes</artifactId>

<version>2.8.0</version>

</dependency>

</dependencies>

</project>

调用服务

package com.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ReferenceConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.dubbo.provider.service.ProviderService;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**

* xml的方式调用

*

*/

public class App

{

public static void main( String[] args ) throws IOException {

ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");

context.start();

ProviderService providerService = (ProviderService) context.getBean("providerService");

String str = providerService.SayHello("hello");

System.out.println(str);

System.in.read();

}

}

3.4 加入zookeeper作为注册中心

在前面的操作中没有使用任何注册中心,用一种直连的方式进行。实际都是使用 dubbo + zookeeper 的方式,使用 zookeeper 作为注册中心,这里介绍 zookeeper 作为注册中心的使用方法。对前面的案例进行改造:

3.4.1 服务提供者修改

修改provider.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

<dubbo:application name="provider" owner="cp">

<dubbo:parameter key="qos.enable" value="true"/>

<dubbo:parameter key="qos.accept.foreign.ip" value="false"/>

<dubbo:parameter key="qos.port" value="55555"/>

</dubbo:application>

<dubbo:monitor protocol="registry"/>

<!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

<!--<dubbo:registry address="N/A"/>-->

<dubbo:registry address="zookeeper://localhost:2181" check="false"/>

<!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->

<dubbo:protocol name="dubbo" port="20880"/>

<!--服务发布的配置,需要暴露的服务接口-->

<dubbo:service

interface="com.dubbo.provider.service.ProviderService"

ref="providerService"/>

<!--Bean bean定义-->

<bean id="providerService" class="com.dubbo.provider.service.ProviderServiceImpl"/>

</beans>

3.4.2 服务消费者修改

修改 consumer.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->

<dubbo:application name="consumer" owner="cp"/>

<!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->

<!--点对点的方式-->

<!--<dubbo:registry address="N/A" />-->

<dubbo:registry address="zookeeper://localhost:2181" check="false"/>

<!--生成一个远程服务的调用代理-->

<!--点对点方式-->

<!--<dubbo:reference id="providerService"

interface="com.dubbo.provider.service.ProviderService"

url="dubbo://192.168.234.1:20880/com.dubbo.provider.service.ProviderService"/>-->

<dubbo:reference id="providerService"

interface="com.dubbo.provider.service.ProviderService"/>

</beans>

总结:加入zookeeper和直接点对点方式的区别就是: dubbo 发布的 url 注册到了 zookeeper,消费端从 zookeeper 消费,zookeeper 相当于一个中介,给消费者提供服务。

3.5注解配置方式

前面使用xml文件配置方式,这里使用注解配置方式,现在微服务都倾向于这种方式,这也是以后发展的趋势, 0配置是以后的趋势。那么如何对 dubbo 使用注解的方式呢?

3.5.1 服务提供者注解配置

接口:

package com.dubbo.provider.service.annotation;

/**

* 注解方式接口

*/

public interface ProviderServiceAnnotation {

String SayHelloAnnotation(String word);

}

实现类

package com.dubbo.provider.service.annotation;

import com.alibaba.dubbo.config.annotation.Service;

/**

* 注解方式实现类

*/

@Service(timeout = 5000)

public class ProviderServiceImplAnnotation implements ProviderServiceAnnotation{

public String SayHelloAnnotation(String word) {

return word;

}

}

1@Service 用来配置 Dubbo 的服务提供方。

2、通过 Spring  Java Config 的技术(@Configuration)和 annotation 扫描(@EnableDubbo)来发现、组装、并向外提供 Dubbo 的服务。

package com.dubbo.provider.configuration;

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ProtocolConfig;

import com.alibaba.dubbo.config.ProviderConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

* 注解方式配置

*/

@Configuration

@EnableDubbo(scanBasePackages = "com.dubbo.provider.service.annotation")

public class DubboConfiguration {

@Bean // #1 服务提供者信息配置

public ProviderConfig providerConfig() {

ProviderConfig providerConfig = new ProviderConfig();

providerConfig.setTimeout(1000);

return providerConfig;

}

@Bean // #2 分布式应用信息配置

public ApplicationConfig applicationConfig() {

ApplicationConfig applicationConfig = new ApplicationConfig();

applicationConfig.setName("dubbo-annotation-provider");

return applicationConfig;

}

@Bean // #3 注册中心信息配置

public RegistryConfig registryConfig() {

RegistryConfig registryConfig = new RegistryConfig();

registryConfig.setProtocol("zookeeper");

registryConfig.setAddress("localhost");

registryConfig.setPort(2181);

return registryConfig;

}

@Bean // #4 使用协议配置,这里使用 dubbo

public ProtocolConfig protocolConfig() {

ProtocolConfig protocolConfig = new ProtocolConfig();

protocolConfig.setName("dubbo");

protocolConfig.setPort(20880);

return protocolConfig;

}

}

分析:通过 @EnableDubbo 指定在com.dubbo.provider.service.annotation 下扫描所有标注有 @Service 的类。

通过 @Configuration 将 DubboConfiguration 中所有的 @Bean 通过 Java Config 的方式组装出来并注入给 Dubbo 服务,也就是标注有 @Service 的类。这其中就包括了:

ProviderConfig:服务提供方配置

ApplicationConfig:应用配置

RegistryConfig:注册中心配置

ProtocolConfig:协议配置

启动服务

package com.dubbo.provider;

import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;

import com.dubbo.provider.configuration.DubboConfiguration;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import sun.applet.Main;

import java.io.IOException;

/**

* 注解启动方式

*/

public class AppAnnotation {

public static void main(String[] args) throws IOException {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DubboConfiguration.class);

context.start();

System.in.read();

}

}

3.5.2 服务消费者注解配置

引用服务

package com.dubbo.consumer.Annotation;

import com.alibaba.dubbo.config.annotation.Reference;

import com.dubbo.provider.service.annotation.ProviderServiceAnnotation;

import org.springframework.stereotype.Component;

/**

* 注解方式的service

*/

@Component("annotatedConsumer")

public class ConsumerAnnotationService {

@Reference

private ProviderServiceAnnotation providerServiceAnnotation;

public String doSayHello(String name) {

return providerServiceAnnotation.SayHelloAnnotation(name);

}

}

引入依赖

<dependency>

<groupId>com.test</groupId>

<artifactId>dubbo-provider</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

组装服务端消费者

package com.dubbo.consumer.configuration;

import com.alibaba.dubbo.config.ApplicationConfig;

import com.alibaba.dubbo.config.ConsumerConfig;

import com.alibaba.dubbo.config.RegistryConfig;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

import java.util.Map;

/**

* 注解配置类

*/

@Configuration

@EnableDubbo(scanBasePackages = "com.dubbo.consumer.Annotation")

@ComponentScan(value = {"com.dubbo.consumer.Annotation"})

public class ConsumerConfiguration {

@Bean // 应用配置

public ApplicationConfig applicationConfig() {

ApplicationConfig applicationConfig = new ApplicationConfig();

applicationConfig.setName("dubbo-annotation-consumer");

Map<String, String> stringStringMap = new HashMap<String, String>();

stringStringMap.put("qos.enable","true");

stringStringMap.put("qos.accept.foreign.ip","false");

stringStringMap.put("qos.port","33333");

applicationConfig.setParameters(stringStringMap);

return applicationConfig;

}

@Bean // 服务消费者配置

public ConsumerConfig consumerConfig() {

ConsumerConfig consumerConfig = new ConsumerConfig();

consumerConfig.setTimeout(3000);

return consumerConfig;

}

@Bean // 配置注册中心

public RegistryConfig registryConfig() {

RegistryConfig registryConfig = new RegistryConfig();

registryConfig.setProtocol("zookeeper");

registryConfig.setAddress("localhost");

registryConfig.setPort(2181);

return registryConfig;

}

}

发起调用

package com.dubbo.consumer;

import com.dubbo.consumer.Annotation.ConsumerAnnotationService;

import com.dubbo.consumer.configuration.ConsumerConfiguration;

import com.dubbo.provider.service.ProviderService;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**

* 注解方式启动

*

*/

public class AppAnnotation

{

public static void main( String[] args ) throws IOException {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);

context.start(); // 启动

ConsumerAnnotationService consumerAnnotationService = context.getBean(ConsumerAnnotationService.class);

String hello = consumerAnnotationService.doSayHello("annotation"); // 调用方法

System.out.println("result: " + hello); // 输出结果

}

}

3.6 主要使用场景:

3.6.1 启动时检查

Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 `check="true"。

3.6.2 集群容错

集群模式

说明

使用方法

Failover Cluster

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

cluster="xxx" xxx:集群模式名称 ,例如cluster="failover"

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

Failsafe Cluster

失败安全,出现异常时,直接忽略。

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

3.6.3 直连服务提供者

直连就是点对点方式,绕过注册中心。在开发及测试环境下,只测试指定服务提供者,只需要直接连接服务端的地即可,这种方式简单。

从0到1搞一波dubbo相关推荐

  1. 即兴操作:详解Linux安装GCC方法-------------------------这操作很简单搞一波试试看

    详解Linux安装GCC方法 起锅烧油先准备七个包配置文件以便于查看 上传http-2.4.25.tar.gz软件包到/opt目录下 解压压缩包 修改配置文件 修改配置文件并启动服务 inux中访问h ...

  2. 频繁爬取天涯的帖子会不会被抓_web爬虫-搞一波天涯论坛帖子练练手

    今天我们将要学习如何使用BeautifulSoup库来抓取网站.BeautifulSoup是一个很好的工具,用于解析HTML代码并准确获取所需的信息.因此,无论您是从新闻网站,体育网站,还是在线商店的 ...

  3. 万向区块链蜂巢学院 | 关于ETH2.0路线图,搞研究的大脑在想什么?

    以太坊2.0是2020年区块链行业最火热的话题之一.万向区块链蜂巢学院线上公开课第42期,邀请了以太坊爱好者社区负责人阿剑.链闻研究总监潘致雄.MYKEY研究部门负责人姚翔.HashKey Capit ...

  4. MVVM?继续搞一波

    前言 又是好久不见了,真的不是因为我懒,是因为公司目前活确实有点着急,所以每天在忙公司的事情. 在五月下旬的时候写过一篇MVVM的文章:MVVM?瞎搞一波?.当时写的时候内心其实很慌,怕写的不好从而误 ...

  5. 【dubbo】No provider available from registry 127.0.0.1:2181 for service com.dubbo.api.service

    页面访问:http://localhost:8062/add?a=111,报报错如下(消费者服务也是报这种错): Whitelabel Error Page This application has ...

  6. 先搞一波kotlin,看它怎么说

    kotlin被谷歌正名都快两个月了,作为Android developer是时候学习一波了,kotlin优点有很多比如完全兼容java,空值处理,语法简洁,支持新特性等等... 废话不多说,直接开始配 ...

  7. 高并发架构系列:如何从0到1设计一个类Dubbo的RPC框架

    优知学院 2019-01-22 18:43:51 之前持续分享的几十期阿里Java面试题中,几乎每次必问Dubbo,比如:"如何从0到1设计一个Dubbo的RPC框架",其实主要考 ...

  8. 【总结】最全1.5万字长文解读7大方向人脸数据集v2.0版,搞计算机视觉怎能不懂人脸...

    人脸图像是计算机视觉领域中研究历史最久,也是应用最广泛的图像.从人脸检测.人脸识别.人脸的年龄表情等属性识别,到人脸的三维重建等,都有非常多的数据集被不断整理提出,极大地促进了该领域的发展. 本次,我 ...

  9. 0. 一字一句的搞懂vue-cli之vue webpack template配置

    此篇文章地址:  https://www.cnblogs.com/xyyt/p/9117361.html webpack--神一样的存在.无论写了多少次,再次相见,仍是初见.有的时候开发vue项目,对 ...

最新文章

  1. 对于数据库连接池的一些思考和MyBatis的集成与使用
  2. 关于ngOptions的键值对
  3. WindowManager如何被Android深度解析(1)
  4. SQL Server中行列转换 Pivot UnPivot (转载)
  5. 在vue中使用express-mock搭建mock服务
  6. JEECG第17期架构培训班15号开班啦!每期十个名额,想报名的抓紧时间啦!
  7. C语言预处理#line、#error
  8. UNIX环境高级编程——创建与打开IPC通道
  9. 计算机文化基础作品ppt,计算机文化基础PPT课件
  10. java poi jar包下载_poi.jar下载-poi.jar包 3.8/3.9/3.10 免费版 - 河东下载站
  11. html返回按钮 超链接,ppt中怎么添加超链接返回按钮
  12. volatile详解
  13. 启发式搜索解决八数码问题
  14. light动名词_英语语法(5)动名词
  15. 网购火车票全攻略(新手+进阶+高手级)
  16. 英文写作盲点-less than 和 fewer than 、only
  17. 7-3 求100以内的素数
  18. 判断设置了css省略号样式的元素是否出现了省略号
  19. 2020年的奋斗目标
  20. 如果我们真的发现了外星人?

热门文章

  1. 前端学习(1696):前端系列javascript之class和继承
  2. 前端学习(1306):node.js模块的加载机制
  3. 前端学习(46):页面导入样式时,使用link和@import有什么区别?
  4. git学习(6):删除github镜像
  5. mybatis学习(8):The server time zone value '???ú±ê×??±??' is unrecognized or represents more
  6. java学习(36):数组排序
  7. [Github项目推荐] 机器学习 Python 知识点速查表
  8. selenium定位元素的方法_selenium定位元素之冻结窗口
  9. Open-Falcon 监控系统监控 MySQL/Redis/MongoDB 状态监控
  10. POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】