从Dubbo到SpringCloud

一、Dubbo与SpringCloud的区别(面试高频问题)

1、定位不同,dubbo是一个开源的分布式架构框架,致力于解决内部或内网的RPC,是SOA(面向服务架构)时代的产物,它专注于服务的调用与治理;而SpringCloud是一个微服务全家桶,工功能远比dubbo丰富,如:网关、更完善的熔断器、分布式配置、服务跟踪、批量任务等

2、接口调用方式不同,dubbo默认是dubbo协议(也支持http协议),一般是以java接口的形式直接调用;SpringCloud是使用HTTP做接口调用,比较灵活不受开发语言限制;二者相比,dubbo接口调用的性能较好(采用Netty的NIO方式实现)

3、组件差异较多,Dubbo是阿里的开源框架,而SpringCloud是基于SpringBoot开发的框架,dubbo一般使用Zookeeper当注册中心,Springcloud一般使用Eureka或naocs

二、Zookeeper与Eureka注册中心的区别

1、Zookeeper使用需要安装,而Eureka是项目中的一个java服务

2、集群设计不同,Zookeeper是主从设计,而Eureka是各节点平等

3、服务订阅方式不同,Zookeeper中的消费者首次启动将订阅服务信息缓存到本地,之后服务的变更会推送给消费者,而Eureka是采用定时轮询的方式去主动拉取服务的更新

三、SpringCloud核心组件

1、zuul(网关):相当于网络服务架构的入口,所有请求必须通过网关转发到具体的服务,主要功能有统一管理微服务请求、负载均衡、动态路由、权限控制、监控、静态资源处理等

2、Eureka(注册中心):用来注册服务,其中包含Eureka Client、Eureka Server

Eureka Client:包含服务提供者,服务消费者,主要负责服务注册、心跳续约与健康状态查询

Eureka Server:提供注册服务,各个节点启动后都会在Eureka Server注册,可用的节点信息可在Eureka Server中的服务注册表中找到

3、Feign:一个HTTP请求的轻量级客户端框架,通过接口+注解的方式发起HTTP请求的调用

具体执行流程如下

a、在主程序上添加@EnableFeignClients注册开启对@FeignClient注解的扫描加载

b、调用接口中的方法时,基于JDK的动态代理,通过InvokeHandler分发远程调用,生成具体的RequestTemplate

c、RequestTemplate生成Request请求,结合Ribbon实现服务负载均衡策略

Feign最核心的就是动态代理,同时整合了Ribbon和Hystrix,具备负载均衡、隔离、熔断和降级功能

4、Ribbon:是一个客户端的负载均衡器,支持简单轮询、权重、随机、重试等多种策略

5、Hystrix:断路器,包含熔断、隔离、降级等功能

四、SpringCloud的使用(注意SpringBoot与SpringCloud的版本兼容性,官网说明

1、创建一个项目,笔者这里的demo项目叫bryant(注意需要创建SpringBoot项目),pom文件配置如下:



    4.0.0
    com.kobe
    bryant
    0.0.1-SNAPSHOT
    pom

    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.9
         
    

    
        
        eureka-server
        
        user-api
        
        user-client
        
        feign-client
    

    
        11
        UTF-8
        UTF-8
        2021.0.5
        0.0.1-SNAPSHOT
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                import
                pom
            
        
    

    
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            javax.xml.bind
            jaxb-api
            2.3.0
        
        
            com.sun.xml.bind
            jaxb-impl
            2.3.0
        
        
            org.glassfish.jaxb
            jaxb-runtime
            2.3.0
        
        
            javax.activation
            activation
            1.1.1
        

    


    bryant
    bryant

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

2、在父项目下创建Eureka服务项目,eureka-server,pom文件配置如下:



    4.0.0
    
        com.kobe
        bryant
        0.0.1-SNAPSHOT
    

    com.kobe
    eureka-server
    jar
    0.0.1-SNAPSHOT

    eureka-server
    eureka-server

    
        11
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    



配置注册中心服务的端口号及其他参数:

#tomcat
server:
  port: 8888

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

spring:
  application:
    name: eureka-server

然后在启动类上加上@EnableEurekaServer注解:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }

}

好了,以上就是注册中心服务创建和配置,启动成功后访问http://localhost:8888会出现如下界面:

从Dubbo到SpringCloud_第1张图片

3、在父项目下创建服务提供者项目,user-api,pom文件如下:



    4.0.0
    
        com.kobe
        bryant
        0.0.1-SNAPSHOT
    

    com.kobe
    user-api
    jar
    0.0.1-SNAPSHOT

    user-api
    user-api

    
        11
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


配置服务端口并在配置文件中指定Eureka注册中心的地址:

#tomcat
server:
  port: 8081

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/

spring:
  application:
    name: user-api

然后在启动类中添加@EnableEurekaClient注解:

@SpringBootApplication
@EnableEurekaClient
public class UserApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApiApplication.class, args);
    }

}

在服务提供者项目简单定义几个http接口:

@RestController
public class UserApiController {

    @Value("${spring.application.name}")
    private String serverName;

    @Value("${server.port}")
    private String port;

    @GetMapping("user/token")
    public String getUserToken() {
        return UUID.randomUUID().toString();
    }

    @GetMapping("user/hi/{name}")
    public String sayHi(@PathVariable String name) {
        return "Hello, " + name + ", I am " + serverName + ", my port is " + port + ".";
    }

}

写好启动服务,刷新注册中心管理页面(http://localhost:8888)能看到已经发现服务:

从Dubbo到SpringCloud_第2张图片

现在可以修改一下服务提供者的端口,再启动一个服务,方便模拟多节点场景:

从Dubbo到SpringCloud_第3张图片

 

4、在父项目下创建rest+ribbon消费者项目,user-client,pom文件如下:



    4.0.0
    
        bryant
        com.kobe
        0.0.1-SNAPSHOT
    

    com.kobe
    user-client
    jar
    0.0.1-SNAPSHOT

    user-api
    user-api


    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

同样是定义端口和配置Eureka地址:

#tomcat
server:
  port: 7071

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/

spring:
  application:
    name: user-client

然后在启动类中添加@EnableEurekaClient、@EnableDiscoveryClient注解,还需要配置一个RestTemplate类,用来调用服务提供者的接口:

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class UserClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserClientApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

现在可以编写controller去调用服务提供者的接口,可以看到http协议后跟的是服务提供者的服务名,后面跟的是其http接口地址:

@RestController
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("user/token")
    public String getUserToken() {
        return restTemplate.getForObject("http://user-api/user/token", String.class);
    }

    @GetMapping("user/hi/{name}")
    public String sayHi(@PathVariable("name") String name) {
        return restTemplate.getForObject("http://user-api/user/hi/" + name, String.class);
    }

}

启动消费者项目注册中心后台能看到如下结果:

从Dubbo到SpringCloud_第4张图片

接下来多次访问一下http://localhost:7071/user/hi/SpringCloud接口试试:

从Dubbo到SpringCloud_第5张图片

 

从Dubbo到SpringCloud_第6张图片

能看到已经实现了负载均衡!

5、在父项目下创建feign消费者项目,pom文件如下:

说明:其中rest+ribbon和feign(轻量级的HTTP请求客户端)只是调用代码风格不同,实际开发中任选其一(推荐用feign)



	4.0.0
	
		com.kobe
		bryant
		0.0.1-SNAPSHOT
	

	com.kobe
	feign-client
	jar
	0.0.1-SNAPSHOT

	feign-client
	feign-client

	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.cloud
			spring-cloud-starter-netflix-eureka-client
		
		
			org.springframework.cloud
			spring-cloud-starter-openfeign
		

	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	


配置feign消费者服务端口号及Eureka注册中心的地址:

#tomcat
server:
  port: 7072

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka/

spring:
  application:
    name: feign-client

在启动类上添加@EnableEurekaClient、@EnableDiscoveryClient、@EnableFeignClient来启用feign功能:

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class FeignClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignClientApplication.class, args);
    }

}

使用feign需要先定义接口,@FeignClient是关键所在,这实际上是对服务提供者的接口的描述,跟定义controller接口相似,具体示例如下:

@FeignClient(value = "user-api")
public interface IUserApiRemoteService {

    @GetMapping("user/token")
    String getToken();

    @GetMapping("user/hi/{name}")
    String sayHi(@PathVariable String name);

}

然后使用就跟平时注入一个普通的service一样,它底层是使用代理来实现的:

@RestController
public class UserController {

    @Autowired
    private IUserApiRemoteService userRemoteService;

    @GetMapping("user/token")
    public String getUserToken() {
        return userRemoteService.getToken();
    }

    @GetMapping("user/hi/{name}")
    public String sayHi(@PathVariable("name") String name) {
        return userRemoteService.sayHi(name);
    }
}

启动该服务后访问http://localhost:7072/user/hi/SpringCloud接口:

从Dubbo到SpringCloud_第7张图片

 从Dubbo到SpringCloud_第8张图片

 以上就是SpringCloud的简单使用,这里没有集成网关,可以根据项目的实际需求来评估是否需要使用网关技术。

你可能感兴趣的:(分布式架构与微服务,dubbo,spring,cloud,springcloud实战,springcloud实例,springcloud教程)