前言

我们前面的博客已经学习了 springboot 如何整合 dubbo 框架
springboot整合dubbo

在整合 SpringCloud 前,大家有没有想过他和 dubbo 有什么差异:

  1. 来源(背景): Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点。Spring Cloud,从命名我们就可以知道,它是Spring Source的产物,Spring社区的强大背书可以说是Java企业界最有影响力的组织了,除了Spring Source之外,还有Pivotal和Netfix是其强大的后盾与技术输出。其中Netflix开源的整套微服务架构套件是Spring Cloud的核心。简而言之dubbo是阿里写的属于国产,springcloud 属于国际版应用更广。

2.注册中心: dubbo支持的注册中心为:Zookeeper(官方推荐)MulticastRedisSimple,我们常用为zk。springcloud 支持的注册中心有EurekaZookeeperConsulNacos,各个注册中心的区别请查阅springcloud四个注册中心的比较这里我使用的是已经闭源的EurekaZooKeeper是个CP强一致性和分区容错性,而EurekaAP原则,舍弃了强一致性,保证了高可用。

  1. 传输: Dubbo由于是二进制的传输,占用带宽会更少;Spring Cloud是http协议传输,带宽会比较多,同时使用http协议一般会使用JSON报文,消耗会更大。但是在国内95%的公司内,网络消耗不是什么太大问题,如果真的成了问题,通过压缩、二进制、高速缓存、分段降级等方法,很容易解。
  2. 开发难度: Dubbo的开发难度较大,原因是dubbo的jar包依赖问题很多大型工程无法解决;Spring Cloud的接口协议约定比较自由且松散,需要有强有力的行政措施来限制接口无序升级
  3. 后续改进: Dubbo通过dubbofilter,很多东西没有,需要自己继承,如监控,如日志,如限流,如追踪
  4. 配置中心: dubbo:如果我们使用配置中心、分布式跟踪这些内容都需要自己去集成,无形中增加了使用难度。
  5. 核心部件的比较:

Dubbo:

  • Provider:暴露服务的提供方,可以通过 jar 或者容器的方式启动服务。
  • Consumer:调用远程服务的服务消费方。
  • Registry:服务注册中心和发现中心。
  • Monitor:统计服务和调用次数,调用时间监控中心。(Dubbo 的控制台页面中可以显示,目前只有一个简单版本。)
  • Container:服务运行的容器。

Spring Cloud:

  • Service Provider: 暴露服务的提供方。
  • Service Consumer:调用远程服务的服务消费方。
  • EureKa Server: 服务注册中心和服务发现中心。

Spring Cloud:提供了微服务的一整套解决方案:服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等

  1. 架构的完整度: Dubbo只是实现了服务治理;Spring Cloud下面有17个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面;一定程度来说,Dubbo只是Spring Cloud Netflix中的一个子集。
  2. 服务依赖方式: Dubbo:服务提供方与消费方通过接口的方式依赖,服务调用设计如下:
  • Interface 层:服务接口层,定义了服务对外提供的所有接口。
  • Molel 层:服务的 DTO 对象层。
  • Business层:业务实现层,实现 Interface 接口并且和 DB 交互。

因此需要为每个微服务定义各自的 Interface 接口,并通过持续集成发布到私有仓库中。调用方应用对微服务提供的抽象接口存在强依赖关系,开发、测试、集成环境都需要严格的管理版本依赖。

Spring Cloud:
服务提供方和服务消费方通过 Json 方式交互,因此只需要定义好相关 Json 字段即可,消费方和提供方无接口依赖。通过注解方式来实现服务配置,对于程序有一定入侵。
通过 Json 交互,省略了版本管理的问题,但是具体字段含义需要统一管理,自身 Rest API 方式交互,为跨平台调用奠定了基础。

总体:

Dubbo:使用Dubbo构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;

Spring Cloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。

优缺点(综上得到):

Dubbo

优点:

1.支持各种通信协议,而且消费方和服务方使用长链接方式交互,通信速度上略胜 ;

2.采用rpc方式,性能上比Spring Cloud的rpc更好;

3.dubbo的网络消耗小于springcloud

缺点:

1.如果我们使用配置中心、分布式跟踪这些内容都需要自己去集成;

2.开发难度较大,原因是dubbo的jar包依赖问题很多大型工程无法解决;

3.

Spring Cloud:

优点:

1、产出于Spring大家族,Spring在企业级开发框架中来头很大,可以保证后续的更新、完善。

2、spring cloud社区活跃,教程丰富,遇到问题很容易找到解决方案;

3、spring cloud功能比dubbo更加完善;

5、spring cloud采用rest访问方式,rest的技术无关性使用效果更棒;

6、spring cloud轻轻松松几行代码就完成了熔断、均衡负责、服务中心的各种平台功能;

7、从公司招聘工程师方面,spring cloud更有优势,因为其技术更新更炫;

8、提供了微服务的一整套解决方案:服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等;作为一个微服务治理的大家伙,考虑的很全面,几乎服务治理的方方面面都考虑到了,方便开发开箱即用;

缺点:

1.如果对于系统的响应时间有严格要求,长链接更合适。

2.接口协议约定比较自由且松散,需要有强有力的行政措施来限制接口无序升级


参考自:

https://blog.csdn.net/u010664947/article/details/80007767

https://blog.csdn.net/zuiyingong6567/article/details/80229310

创建项目

使用 Spring Initializr 新建一个项目命名为: springcloud-parent,删除多余的文件,并新建三个子模块分别为:springcloud-eureka-serverspringcloud-memberspringcloud-order
image.png

父工程 pom.xml配置文件spring-boot 版本这里选用 2.0.1.RELEASE

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <packaging>pom</packaging>
 <modules> <module>springcloud-eureka-server</module>
 <module>springcloud-member</module>
 <module>springcloud-order</module>
 </modules> <parent> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.0.1.RELEASE</version>
 <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.baba.wlb</groupId>
 <artifactId>springcloud-parent</artifactId>
 <version>1.0-SNAPSHOT</version>
 <name>springcloud-parent</name>
 <description>Demo project for Spring Boot</description>
 <properties> <java.version>1.8</java.version>
 </properties>
 <dependencies> <dependency> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-devtools</artifactId>
 <scope>runtime</scope>
 <optional>true</optional>
 </dependency> <dependency> <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <optional>true</optional>
 </dependency> <dependency> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
 </dependencies>
 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 </exclude> </excludes> </configuration> </plugin> </plugins> </build>
</project>

子模块

springcloud-eureka-server模块:

image.png

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">
 <parent> <artifactId>springcloud-parent</artifactId>
 <groupId>com.baba.wlb</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent> <modelVersion>4.0.0</modelVersion>
 <artifactId>springcloud-eureka-server</artifactId>
 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-dependencies</artifactId>
 <version>Finchley.M7</version>
 <type>pom</type>
 <scope>import</scope>
 </dependency> </dependencies> </dependencyManagement>
 <dependencies> <!--SpringCloud Eureka Server-->
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
 </dependency> </dependencies>
 <!--注意:这里必须添加,否则各种依赖有问题-->
 <repositories>
 <repository> <id>spring-milestones</id>
 <name>Spring Milestones</name>
 <url>https://repo.spring.io/libs-milestone</url>
 <snapshots> <enabled>false</enabled>
 </snapshots> </repository> </repositories></project>

application.yml配置文件:

##服务端口号
server:
  port: 8100
eureka:
  instance:
    ##服务注册中心ip地址
 hostname: 127.0.0.1
  client:
    serviceUrl:
      ##注册地址
 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    ##因为自己是注册中心,是否需要自己将自己注册到注册中心(集群的时候为true)
 register-with-eureka: false
 ##因为自己是注册中心,不需要去检索服务信息
 fetch-registry: false

EurekaServerApplication 启动类:

package com.baba.wlb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
    //@EnableEurekaServer 表示开启Eureka服务 开启注册中心
 public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
 }
}

springcloud-member模块:

image.png

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">
 <parent> <artifactId>springcloud-parent</artifactId>
 <groupId>com.baba.wlb</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent> <modelVersion>4.0.0</modelVersion>
 <artifactId>springcloud-member</artifactId>
 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-dependencies</artifactId>
 <version>Finchley.M7</version>
 <type>pom</type>
 <scope>import</scope>
 </dependency> </dependencies> </dependencyManagement>
 <dependencies> <!--Springboot 整合web组件-->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <!--SpringBoot 整合eureka客户端-->
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
 </dependencies>
 <!--注意:这里必须添加,否则各种依赖有问题-->
 <repositories>
 <repository> <id>spring-milestones</id>
 <name>Spring Milestones</name>
 <url>https://repo.spring.io/libs-milestone</url>
 <snapshots> <enabled>false</enabled>
 </snapshots> </repository> </repositories></project>

application.yml配置文件:

spring:
  profiles:
    active: dev

application-dev.yml配置文件:

##服务端口号
server:
  port: 8000
spring:
  application:
    ##服务别名--服务注册到Eureka名称
 name: app-member
eureka:
  client:
    service-url:
      ##当前服务注册到Eureka服务地址
 defaultZone: http://localhost:8100/eureka
    register-with-eureka: true
 ## 需要检索服务信息
 fetch-registry: true

application-prod.yml配置文件:

##服务端口号
server:
  port: 8010
spring:
  application:
    ##服务别名--服务注册到Eureka名称
 name: app-member
eureka:
  client:
    service-url:
      ##当前服务注册到Eureka服务地址
 defaultZone: http://localhost:8100/eureka
    register-with-eureka: true
    ## 需要检索服务信息
 fetch-registry: true

MemberApiController 控制页面:

package com.baba.wlb.api.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author wulongbo
 * @Date 2021/1/9 15:20
 * @Version 1.0
 */@RestController
public class MemberApiController {
    @Value("${server.port}")
    private String serverPort;
 @RequestMapping("/getMember")
    public String getMember() {
        return "我是会员服务!端口号:"+serverPort;
 }
}

AppMember.java 启动类:

package com.baba.wlb.api.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
 * @Author wulongbo
 * @Date 2021/1/9 15:22
 * @Version 1.0
 */
@EnableEurekaClient
@SpringBootApplication
public class AppMember {
    public static void main(String[] args) {
        SpringApplication.run(AppMember.class,args);
 }
}

springcloud-order模块:

image.png

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">
 <parent> <artifactId>springcloud-parent</artifactId>
 <groupId>com.baba.wlb</groupId>
 <version>1.0-SNAPSHOT</version>
 </parent> <modelVersion>4.0.0</modelVersion>
 <artifactId>springcloud-order</artifactId>
 <!--管理依赖-->
 <dependencyManagement>
 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-dependencies</artifactId>
 <version>Finchley.M7</version>
 <type>pom</type>
 <scope>import</scope>
 </dependency> </dependencies> </dependencyManagement>
 <dependencies> <!--Springboot 整合web组件-->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <!--SpringBoot 整合eureka客户端-->
 <dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
 </dependencies>
 <!--注意:这里必须添加,否则各种依赖有问题-->
 <repositories>
 <repository> <id>spring-milestones</id>
 <name>Spring Milestones</name>
 <url>https://repo.spring.io/libs-milestone</url>
 <snapshots> <enabled>false</enabled>
 </snapshots> </repository> </repositories></project>

application.yml 配置文件:

##服务端口号
server:
  port: 8200
spring:
  application:
    ##服务别名--服务注册到Eureka名称
 name: app-order
eureka:
  client:
    service-url:
      ##当前服务注册到Eureka服务地址
 defaultZone: http://localhost:8100/eureka
    register-with-eureka: true
 ## 需要检索服务信息
 fetch-registry: true

OrderApiController 控制页面:
springCloud中,两种方式调用(rest/feign)

package com.baba.wlb.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
 * @Author wulongbo
 * @Date 2021/1/9 15:32
 * @Version 1.0
 */@RestController
public class OrderApiController {
    @Autowired
 private RestTemplate restTemplate;
 /**
 * springCloud中,两种方式调用(rest/feign)
 *
 * @return
 */
 // 订单服务调用会员服务
 @RequestMapping("/getOrder")
    public String getOrder() {
        // 有两种调用方式,一种是采用服务别名方式调用,另一种是使用别名去注册中心上获取对应服务调用地址
 // 第一种方式
 String url = "http://dy-202006281547:8000/getMember";
 // 第二种方式
 url = "http://app-member/getMember";
 String result = restTemplate.getForObject(url, String.class);
 return "订单服务调用会员服务:" + result;
 }
}

AppOrder.java 启动类:
在启动类中注入RestTemplate bean对象。

package com.baba.wlb.api.controller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
 * @Author wulongbo
 * @Date 2021/1/9 15:39
 * @Version 1.0
 */@SpringBootApplication
@EnableEurekaClient
public class AppOrder {
    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class,args);
 // 第二种方式 如果使用rest方式以别名方式进行调用依赖ribbon负载均衡器
 // 第二种方式 @LoadBalanced能让restTemplate 模板在请求时拥有客户端负载均衡的能力
 }
    // 解决RestTemplate 找不到原因, 把RestTemplate注册到Springboot容器中 @Bean
 // 第一种方式
//    @Bean
//    RestTemplate restTemplate(){
//        return new RestTemplate();
//    }
 // 第二种方式 @LoadBalanced能让restTemplate 模板在请求时拥有客户端负载均衡的能力
 @Bean
 @LoadBalanced RestTemplate restTemplate(){
        return new RestTemplate();
 }
}

启动项目

启动 EurekaServerApplication Eureka服务 开启注册中心

image.png

启动 member服务:

  • 启动AppMember.java,加载的是dev开发环境

image.png
并访问http://localhost:8100/,可以看到注册了别名为 APP-MEMBER的服务
image.png

  • 再启动生产环境,这里我们使用直接启动jar包的方式
  1. 找到jar包位置image.png

为:E:\ideaworkspaceback\springcloud-parent\springcloud-eureka-server\target
2.打开 Terminal
image.png
3.执行命令:java -jar E:\ideaworkspaceback\springcloud-parent\springcloud-member\target\springcloud-member-1.0-SNAPSHOT.jar --spring.profiles.active=prod 启动生产环境
image.png
4.访问http://localhost:8100/,可以看到注册了别名为 APP-MEMBER的服务有两个
image.png
我们点击上图服务地址,并修改http://dy-202006281547:8000/infohttp://dy-202006281547:8000/getMember即可访问member服务
image.png

启动 order服务:

启动AppOrder.java
image.png
并访问http://localhost:8100/,可以看到注册了别名为 APP-ORDER的服务
image.png

测试

Postman 访问localhost:8084/orderToMember
image.png
多次提交可发现做了负载均衡。

总结

springcloud集成Eureka还是很简单,使用注解就完事了!


isWulongbo
228 声望26 粉丝

在人生的头三十年,你培养习惯,后三十年,习惯铸就你