SpringBoot学习笔记-14:第十四章-SpringBoot 与分布式

第十四章-SpringBoot 与分布式

Dubbo 简介

分布式应用,国内常用组合 Zookeeper + Dubbo
SpringBoot 使用 SpringCloud

Zookeeper 分布式应用程序协调服务
Dubbo Alibaba 开源的分布式服务框架,服务提供方 Provider+ 服务消费方 Consumer

安装 zookeeper

docker pull zookeeper

# EXPOSE 2181 2888 3888 8080
docker run --name zk01 -p 2181:2181 --restart always -d zookeeper

创建一个空工程,两个 spring-web 模块

provider-ticket
consumer-ticket

1、将服务提供者注册到注册中心
2、引入 dubbo 和 zkclient 依赖
3、配置 dubbo 的扫描包和注册中心地址
4、使用@Service 发布服务

https://github.com/alibaba/dubbo-spring-boot-starter

provider-ticket 提供者

引入依赖 pom.xml

<dependency>
    <groupId>com.alibaba.spring.bootgroupId>
    <artifactId>dubbo-spring-boot-starterartifactId>
    <version>2.0.0version>
dependency>

<dependency>
    <groupId>com.101tecgroupId>
    <artifactId>zkclientartifactId>
    <version>0.9version>
dependency>

配置 application.properties

spring.dubbo.application.name=privoder-ticket
spring.dubbo.server=true

#注册中心地址
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181

spring.dubbo.scan=com.example.ticket.service

服务接口

package com.example.ticket.service;

public interface TicketService {
    public String getTicket();
}

发布服务实现

package com.example.ticket.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.example.ticket.service.TicketService;
import org.springframework.stereotype.Component;

@Component
@Service // 发布服务
public class TicketServiceImpl implements TicketService {
    @Override
    public String getTicket() {
        return "门票";
    }
}

开启配置可用

package com.example.ticket;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubboConfiguration
@SpringBootApplication
public class ProviderTicketApplication {

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

}

consumer-ticket 消费者

引入依赖

<dependency>
    <groupId>com.alibaba.spring.bootgroupId>
    <artifactId>dubbo-spring-boot-starterartifactId>
    <version>2.0.0version>
dependency>

<dependency>
    <groupId>com.101tecgroupId>
    <artifactId>zkclientartifactId>
    <version>0.9version>
dependency>

配置 application.properties

spring.dubbo.application.name=consumer-ticket

#注册中心地址
spring.dubbo.registry.address=zookeeper://127.0.0.1:2181

暴露接口

package com.example.ticket.service;

public interface TicketService {
    public String getTicket();
}

用户服务接口

package com.example.ticket.service;

public interface UserService {
    public String getTicket();
}

用户服务实现

package com.example.ticket.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.example.ticket.service.TicketService;
import com.example.ticket.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Reference
    TicketService ticketService;

    @Override
    public String getTicket() {
        return ticketService.getTicket();
    }
}

开启配置可用

package com.example.ticket;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubboConfiguration
@SpringBootApplication
public class ConsumerTicketApplication {

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

}

测试

package com.example.ticket;

import com.example.ticket.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ConsumerTicketApplicationTests {

    @Autowired
    UserService userService;

    @Test
    void contextLoads() {
        String ticket = userService.getTicket();
        System.out.println(ticket);
    }

}

SpringCloud-Eureka 注册中心

SpringCloud 是一个分布式的整体解决方案

5 大常用组件

  • 服务发现 Netflix Eureka
  • 客户端负载均衡 Netflix Ribbon
  • 断路器 Netflix Hystrix
  • 服务网关 Netflix Zuul
  • 分布式配置 Spring Cloud Config

pom.xml


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.2.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>com.examplegroupId>
    <artifactId>eureka-demoartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>eureka-demoname>
    <description>Demo project for Spring Bootdescription>

    <properties>
        <java.version>1.8java.version>
        <spring-cloud.version>Hoxton.SR6spring-cloud.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
    dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

project>

application.properties


server.port=8761

#eureka主机名
eureka.instance.hostname=eureka-server

# 不把自己注册在eureka上
eureka.client.register-with-eureka=false

# 不从eureka上获取服务注册信息
eureka.client.fetch-registry=false

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
package com.example.eurekademo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * 注册中心
 * http://localhost:8761/
 */
@EnableEurekaServer  // 启用注册中心
@SpringBootApplication
public class EurekaDemoApplication {

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

}

启用注册中心:http://localhost:8761/

服务注册(服务提供者)

pom.xml


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.2.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>com.examplegroupId>
    <artifactId>provider-demoartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>provider-demoname>
    <description>Demo project for Spring Bootdescription>

    <properties>
        <java.version>1.8java.version>
        <spring-cloud.version>Hoxton.SR6spring-cloud.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
    dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

project>

application.properties

server.port=8002
spring.application.name=provider-demo

#注册服务的时候使用ip地址
eureka.instance.prefer-ip-address=true

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
package com.example.providerdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 服务提供者
 */
@SpringBootApplication
public class ProviderDemoApplication {

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

}

服务

package com.example.providerdemo.service;

import org.springframework.stereotype.Service;

@Service
public class TicketService {
    public String getTicket(){
        return "电影票8001";
        // return "电影票8002";
    }
}

接口

package com.example.providerdemo.controller;

import com.example.providerdemo.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TicketController {
    @Autowired
    TicketService ticketService;

    @GetMapping("/ticket")
    public String getTicket(){
        return ticketService.getTicket();
    }
}

服务发现&服务消费者

pom.xml


<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.0modelVersion>
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.3.2.RELEASEversion>
		<relativePath/> 
	parent>
	<groupId>com.examplegroupId>
	<artifactId>consumer-demoartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<name>consumer-demoname>
	<description>Demo project for Spring Bootdescription>

	<properties>
		<java.version>1.8java.version>
		<spring-cloud.version>Hoxton.SR6spring-cloud.version>
	properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintagegroupId>
					<artifactId>junit-vintage-engineartifactId>
				exclusion>
			exclusions>
		dependency>
	dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
		dependencies>
	dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
			plugin>
		plugins>
	build>

project>

application.properties

server.port=8200
spring.application.name=consumer-demo

#注册服务的时候使用ip地址
eureka.instance.prefer-ip-address=true

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
package com.example.consumerdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * 服务消费者
 */
@EnableDiscoveryClient // 开启服务发现
@SpringBootApplication
public class ConsumerDemoApplication {

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

	@LoadBalanced // 开启负载均衡机制
	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}
}

package com.example.consumerdemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class UserController {

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("buy")
    public String getTicket(){
        String ticket = restTemplate.getForObject("http://PROVIDER-DEMO/ticket", String.class);
        return "buy" + ticket;
    }
}

你可能感兴趣的:(SpringBoot学习笔记)