SpringCloud简单入门

本文详细介绍了使用SpringCloud搭建微服务架构的过程,包括服务注册中心、服务提供者和服务消费者的创建,以及通过Ribbon和RestTemplate实现的服务间负载均衡调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在学习SpringCloud遇到过许多坑,这里记录一下。

首先,新建一个maven pom工程,命名为spring-cloud-demo-parent,该工程作为父工程

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>
  	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
  	<groupId>com.huangbl</groupId>
  	<artifactId>spring-cloud-demo-parent</artifactId>
  	<version>1.0.0-SNAPSHOT</version>
  	<packaging>pom</packaging>
  	<name>spring-cloud-demo-parent</name>
  	
  	<properties>
  		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
	</properties>
  	
  	<dependencies>
  		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
  	</dependencies>
  	
  	<dependencyManagement>
  		<dependencies>
  			<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
  		</dependencies>
  	</dependencyManagement>
  	
  	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
  	
</project>

一、创建服务注册中心

在spring-cloud-demo-parent中新建一个模块cloud-demo-registry-center,其pom.xml的内容为

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  	<modelVersion>4.0.0</modelVersion>
  	<parent>
    	<groupId>com.huangbl</groupId>
    	<artifactId>spring-cloud-demo-parent</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
  	</parent>
  	<artifactId>cloud-demo-registry-center</artifactId>
  	<packaging>war</packaging>
  	<name>cloud-demo-registry-center Maven Webapp</name>
  	<url>http://maven.apache.org</url>
  	<dependencies>
  		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
  	</dependencies>
  	<build>
    	<finalName>cloud-demo-registry-center</finalName>
    	<plugins>
            <!--<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.huangbl.cloud.registry.center.Application</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  	</build>
</project>

新建包名com.huangbl.cloud.registry.center,并在该包下建立Application和ServletInitializer.java两个类,其内容分别为:

Application.java

package com.huangbl.cloud.registry.center;

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

/**
 * @className Application
 * @description TODO
 * @author huangbl
 * @date 2019/02/14 17:01
 * @return
 */
@EnableEurekaServer
@SpringBootApplication
public class Application {

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

其中,@EnableEurekaServer注解标识这是一个服务注册中心

 

ServletInitializer.java

package com.huangbl.cloud.registry.center;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

}

在src/main/resources下新建application.properties

server.port=8081
server.servlet.context-path=/cloud-demo-registry-center

spring.application.name=eureka-cloud-demo-registry-center

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

其中

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

表示这是一个eureka server,否则程序会尝试注册成eureka client。

此时,运行Application.java,地址栏输入“http://127.0.0.1:8081/cloud-demo-registry-center/”可进入eureka server界面

二、创建服务提供者

在spring-cloud-demo-parent内建立一个maven模块cloud-demo-provider,其pom.xml内容为

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  	<modelVersion>4.0.0</modelVersion>
  	<parent>
    	<groupId>com.huangbl</groupId>
    	<artifactId>spring-cloud-demo-parent</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
  	</parent>
  	<artifactId>cloud-demo-provider</artifactId>
  	<packaging>war</packaging>
  	<name>cloud-demo-provider Maven Webapp</name>
  	<url>http://maven.apache.org</url>
  	<dependencies>
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  	</dependencies>
  	<build>
    	<finalName>cloud-demo-provider</finalName>
    	<plugins>
            <!--<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.huangbl.cloud.provider.Application</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  	</build>
</project>

新建包com.huangbl.cloud.provider,在该包下建立Application.java和ServletInitializer.java两个文件,文件内容和cloud-demo-registry-center中的大致相同,唯一不同的是Application.java中将@EnableEurekaServer换成@EnableEurekaClient

在src/main/resources下新建application.properties,文件内容为

server.port=8082
server.servlet.context-path=/cloud-demo-provider

spring.application.name=eureka-cloud-demo-provider

eureka.client.service-url.defaultZone=http://127.0.0.1:8081/cloud-demo-registry-center/eureka

其中spring.application.name是向服务注册中心注册时的Application名称,后面服务消费者访问服务提供者相关接口时也需要用到,而eureka.client.service-url.defaultZone是连接服务注册中心的地址,这里有个坑需要注意一下,如果服务注册中心(cloud-demo-registry-center)设置了server.servlet.context-path,假设此时该值为cloud-demo-registry-center,则cloud-demo-provider中eureka.client.service-url.defaultZone的值需要在eureka前加上cloud-demo-registry-center,即“http://127.0.0.1:8081/cloud-demo-registry-center/eureka”,否则为“http://127.0.0.1:8081/eureka”。

在com.huangbl.cloud.provider下新建controller包,并创建UserController.java

package com.huangbl.cloud.provider.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

	
	@RequestMapping("/find")
	public String find(String nickName) {
		String result = "Hello " + nickName + ",this is cloud-demo-provider";
		return result;
	}
	
}

三、创建服务消费者

同样的道理,在spring-cloud-demo-parent中建立子模块cloud-demo-consumer,其pom.xml内容为

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  	<modelVersion>4.0.0</modelVersion>
  	<parent>
    	<groupId>com.huangbl</groupId>
    	<artifactId>spring-cloud-demo-parent</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
  	</parent>
  	<artifactId>cloud-demo-consumer</artifactId>
  	<packaging>war</packaging>
  	<name>cloud-demo-consumer Maven Webapp</name>
  	<url>http://maven.apache.org</url>
  	<dependencies>
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
  	</dependencies>
  	<build>
    	<finalName>cloud-demo-consumer</finalName>
    	<plugins>
            <!--<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.huangbl.cloud.consumer.Application</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  	</build>
</project>

新建com.huangbl.cloud.consumer包,在该包下建立Application.java和ServletInitializer.java文件

Application.java

package com.huangbl.cloud.consumer;

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.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @className Application
 * @description TODO
 * @author huangbl
 * @date 2018/11/26 17:01
 * @return
 */
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

	@Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
	
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

由于本文中服务与服务之间的调用采用ribbon+restTemplate(ribbon是一个负载均衡客户端,如果服务提供者有多个,则会自动选择其中一个)的方式,所以需要服务启动的时候注入RestTemplate。

ServletInitializer.java内容与前面的一样

 

在src/main/resources下新建application.properties

server.port=8083
server.servlet.context-path=/cloud-demo-consumer

spring.application.name=eureka-cloud-demo-consumer
eureka.client.service-url.defaultZone=http://127.0.0.1:8081/cloud-demo-registry-center/eureka

在com.huangbl.cloud.consumer下新建controller包,创建TestController.java

package com.huangbl.cloud.consumer.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;

@RestController
@RequestMapping("/test")
public class TestController {

	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping("/index")
	public String index() {
		String result = restTemplate.getForObject("http://EUREKA-CLOUD-DEMO-PROVIDER/cloud-demo-provider/user/find?nickName=sheep", String.class);
		return result;
	}
	
}

上面的代码就完成了调用服务生产者的接口,其中的“EUREKA-CLOUD-DEMO-PROVIDER”就是服务提供者中配置的spring.application.name(这里有个坑,访问的名称需要以http://127.0.0.1:8081/cloud-demo-registry-center/界面上显示的为准,界面显示的为全大写,而我设置的是小写),“http://EUREKA-CLOUD-DEMO-PROVIDER”会在请求时替换成实际的服务提供者的ip和端口,不能直接写成ip+端口的方式,这样无法请求而且也达不到负载均衡的效果。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值