Spring Cloud微服务搭建

目录

一、创建springcloud项目

二、创建eureka-server项目-高可用服务注册中心

三、创建eureka-client项目-服务提供者

四、创建ribbon-rest项目-服务消费者(rest方式负载均衡调用)

五、创建feign-hystrix项目-服务消费者(声明式HTTP调用、服务降级处理)

六、创建zuul项目-网关(过滤请求、路由)

七、创建zipkin-server项目-服务调用链路追踪

八、创建config-server项目-配置中心

九、完整代码


一、创建springcloud项目

打开idea创建maven多模块项目:springcloud,作为一个父工程,然后修改pom文件,引入Spring Cloud相关依赖,如下:

<?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.demo</groupId>
	<artifactId>springcloud</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>

	<name>springcloud</name>
	<description>Demo project for Spring Cloud</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
		<relativePath/>
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.cloud.version>Finchley.RELEASE</spring.cloud.version>
	</properties>

	<dependencies>
		<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>

	<modules>
	</modules>
</project>

二、创建eureka-server项目-高可用服务注册中心

在springcloud下创建子模块:eureka-server,pom文件引入以下依赖:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

新建配置文件:application.yml,添加eureka服务端相关配置,如下:

spring:
 application:
  name: eureka-server
eureka:
  instance:
    prefer-ip-address: true
  server:
    enable-self-preservation: false
---
spring:
  profiles: eureka-server-1
server:
   port: 8081
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8082/eureka/
---
spring:
  profiles: eureka-server-2
server:
   port: 8082
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

这里配置了两个profile:eureka-server-1、eureka-server-2,并且让两个Eureka Server相互注册,实现高可用。

然后,编写启动类,在启动类上添加@EnableEurekaServer,声明这是一个Eureka Server:

/**
 * eureka 服务注册中心
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}
	
}

启动后访问:http://localhost:8081,可以看到如下界面:

三、创建eureka-client项目-服务提供者

在springcloud下创建子模块:eureka-client,pom文件引入以下依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

新建配置文件:application.yml,添加eureka客户端相关配置,如下:

spring:
  application:
    name: eureka-client
---
spring:
  profiles: eureka-client-1
server:
  port: 8084
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/
---
spring:
  profiles: eureka-client-2
server:
  port: 8085
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8082/eureka/

这里同样配置了两个profile:eureka-client-1、eureka-client-2,并且分别注册到两个Eureka Server。

编写启动类,添加@EnableDiscoveryClient注解,声明这是一个服务提供者,如下:

/**
 * eureka 服务提供者
 */
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class EurekaClientApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(EurekaClientApplication.class, args);
	}
	
	@Value("${server.port}")
	private int port;
	
	@RequestMapping("hello")
	public String hello(String name) {
		return port + ":hello world, " + name;
	}
	
}

然后分别启动eureka-client-1、eureka-client-2,再次访问:http://localhost:8081,如下:

可以看到Eureka Client服务已经注册到Eureka Server集群上了,访问:http://localhost:8084/hello,正常返回如下:

8084:hello world, null

四、创建ribbon-rest项目-服务消费者(rest方式负载均衡调用)

在springcloud下创建子模块:ribbon-rest,pom文件引入以下依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</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>

新建配置文件:application.yml,添加eureka客户端相关配置,如下:

server:
  port: 8088

spring:
  application:
    name: ribbon-rest

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

接着编写启动类,配置RestTemplate Bean,添加@LoadBalanced注解,开启负载均衡调用,如下:

/**
 * robbin + rest 方式调用服务
 * robbin 实现负载均衡调用服务,默认轮询
 */
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class RobbinRestApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(RobbinRestApplication.class, args);
	}
	
	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping("hello")
	public String hello(String name) {
		return restTemplate.getForObject("http://EUREKA-CLIENT/hello?name=" + name, String.class);
	}
	
}

然后启动ribbon-rest,访问:http://localhost:8081,如下:

可以看到ribbon-rest服务已经注册到Eureka Server集群上了,访问:http://localhost:8088/hello,会交替返回如下内容:

8084:hello world, null

8085:hello world, null

说明消费者以轮询的在方式访问不同的服务提供者实例。

五、创建feign-hystrix项目-服务消费者(声明式HTTP调用、服务降级处理)

在springcloud下创建子模块:feign-hystrix,pom文件引入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</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-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

新建配置文件:application.yml,添加eureka客户端相关配置以及hystrix熔断配置,如下:

server:
  port: 8087

spring:
  application:
    name: feign-hystrix

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

feign:
  hystrix:
    enabled: true

这里以feign方式调用服务,需要写一个接口:IHelloService,添加@FeignClient,表明这是一个feign客户端,同时通过注解的fallback属性指定服务降级的实现类:HelloServiceFallback,在这个类中进行服务的容错处理。

@FeignClient(value = "EUREKA-CLIENT", fallback = HelloServiceFallback.class)
public interface IHelloService {

	@RequestMapping("/hello")
	public String hello(@RequestParam(value = "name") String name);
	
}
@Component
public class HelloServiceFallback implements IHelloService {

	@Override
	public String hello(String name) {
		// TODO Auto-generated method stub
		return name + " sorry, something wrong";
	}

}

接着编写启动类,添加@EnableFeignClients注解,开启声明式http调用。注入IHelloService,调用服务,如下:

/**
 * feign 方式调用服务
 * feign 声明式http客户端,集成robbin,实现负载均衡
 * 整合hystrix,实现熔断,服务降级
 * hystrix 当服务不可用达到阀值时,直接执行fallback方法返回,不用等到超时
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@RestController
public class FeignHystrixApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(FeignHystrixApplication.class, args);
	}
	
	@Autowired
	private IHelloService iHelloService;
	
	@RequestMapping("/hello")
	public String hello(String name) {
		return iHelloService.hello(name);
	}
	
}

然后启动feign-hystrix,访问:http://localhost:8081,如下:

可以看到feign-hystrix服务已经注册到Eureka Server集群上了,访问:http://localhost:8087/hello,同样会交替返回如下内容:

8084:hello world, null

8085:hello world, null

然后停止eureka-client-1、eureka-client-2,再次访问:http://localhost:8087/hello,会返回如下内容:

null sorry, something wrong

说明由于服务提供者不可用,feign进行了服务降级处理。

六、创建zuul项目-网关(过滤请求、路由)

在springcloud下创建子模块:zuul,pom文件引入以下依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</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-zuul</artifactId>
</dependency>

新建配置文件:application.yml,添加eureka客户端相关配置以及zuul路由配置,如下:

server:
  port: 8089

spring:
  application:
    name: eureka-client-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

zuul:
  routes:
    ribbon:
      path: /ribbon/**
      serviceId: RIBBON-REST
    feign:
      path: /feign/**
      serviceId: FEIGN-HYSTRIX

根据routes配置,zuul会将请求路径匹配/ribbon/**的请求转发给RIBBON-REST服务的实例。

同时,编写过滤器:TokenFilter,实现统一的请求过滤:

@Component
public class TokenFilter extends ZuulFilter {

	/**
	 * 过滤器具体实现
	 */
	@Override
	public Object run() throws ZuulException {
		// TODO Auto-generated method stub
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		Object accessToken = request.getParameter("token");
		if (accessToken == null) {
			ctx.setSendZuulResponse(false);
			try {
				ctx.getResponse().getWriter().write("sorry, you do not have a token");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
		return null;
	}

	/**
	 * 返回是否需要过滤(执行run函数),true表示要,false表示不要
	 */
	@Override
	public boolean shouldFilter() {
		// TODO Auto-generated method stub
		return true;
	}

	/**
	 * 返回过滤器执行的顺序,越小越先执行,0最高
	 */
	@Override
	public int filterOrder() {
		// TODO Auto-generated method stub
		return 0;
	}

	/**
	 * 返回生命周期不同的过滤器类型
	 * pre:路由之前
	 * routing:路由之时
	 * post: 路由之后
	 * error:发送错误调用
	 */
	@Override
	public String filterType() {
		// TODO Auto-generated method stub
		return "pre";
	}

}

接着编写启动类,添加@EnableZuulProxy注解,开启服务网关,如下:

/**
 * zuul 网关组件,实现路由转发、过滤功能
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ZuulApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(ZuulApplication.class, args);
	}
	
}

然后启动zuul,访问:http://localhost:8081,如下:

可以看到zuul服务已经注册到Eureka Server集群上了,访问:http://localhost:8089/feign/hello,因为过滤器会拦截没有token的请求,所以此时会返回如下内容:

sorry, you do not have a token

然后加上token,再次访问:http://localhost:8089/feign/hello?token=token,会返回如下内容:

null sorry, something wrong

这是因为前面停止eureka-client-1、eureka-client-2,feign进行了降级处理,说明zuul已经根据路由配置把请求转发给了FEIGN-HYSTRIX服务实例。

七、创建zipkin-server项目-服务调用链路追踪

在springcloud下创建子模块:zipkin-server,pom文件引入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-autoconfigure-ui</artifactId>
    <version>2.11.5</version>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-server</artifactId>
    <version>2.11.5</version>
</dependency>

新建配置文件:application.yml,配置如下:

server:
  port: 8094

spring:
  application:
    name: zipkin-server

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

management:
  metrics:
    web:
      server:
        auto-time-requests: false

接着编写启动类,添加@EnableZipkinServer注解,开启Zipkin Server,如下:

/**
 * 链路追踪
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableZipkinServer
public class ZipkinServerApplication {
    public static void main( String[] args )
    {
        SpringApplication.run(ZipkinServerApplication.class, args);
    }
}

然后启动zipkin-server,访问:http://localhost:8081,如下:

可以看到zipkin-server服务已经注册到Eureka Server集群上了,访问:http://localhost:8094/zipkin/,会出现如下界面:

然后修改eureka-client、ribbon-rest、feign-hystrix、zuul的pom文件,引入zipkin客户端依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

修改application.yml,添加zipkin配置如下:

spring:
  zipkin:
    base-url: http://zipkin-server/
  sleuth:
    sampler:
      probability: 1

重新启动,访问:http://localhost:8089/feign/hello?token=token,接着再次访问:http://localhost:8094/zipkin/,就可以看到服务之间调用的信息了,如下:

八、创建config-server项目-配置中心

在springcloud下创建子模块:config-server,pom文件引入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

新建配置文件:application.yml,配置如下:

spring:
  profiles:
    active: native
  application:
    name: config-server
server:
  port: 8090
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

接着编写启动类,添加@EnableConfigServer注解,开启Config Server,如下:

/**
 * 配置中心
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigServerApplication {

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

}

然后启动config-server,访问:http://localhost:8081,如下:

 

可以看到config-server服务已经注册到Eureka Server集群上了。

然后修改eureka-client、ribbon-rest、feign-hystrix、zuul、zipkin-server的pom文件,引入config client客户端依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

以eureka-client为例,复制application.yml到config-server项目的resources下并重命名为eureka-client.yml,接着注释掉application.yml所有配置,如下:

#spring:
#  zipkin:
#    base-url: http://zipkin-server/
#  sleuth:
#    sampler:
#      probability: 1
#  application:
#    name: eureka-client
#---
#spring:
#  profiles: eureka-client-1
#server:
#  port: 8084
#eureka:
#  client:
#    serviceUrl:
#      defaultZone: http://localhost:8081/eureka/
#---
#spring:
#  profiles: eureka-client-2
#server:
#  port: 8085
#eureka:
#  client:
#    serviceUrl:
#      defaultZone: http://localhost:8082/eureka/

然后eureka-client新建bootstrap.yml配置文件,添加Config Server配置(ConfigClient 服务启动后,默认会先访问bootstrap.yml,然后绑定ConfigServer,然后从ConfigServer获取application.yml 配置),如下:

spring:
  cloud:
    config:
      name: eureka-client
      label: master
      discovery:
        enabled: true
        service-id: config-server
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

ribbon-rest、feign-hystrix、zuul、zipkin-server等模块同理,在config-server的resources下新建配置文件,注释原来application.yml配置,新增bootstrap.yml配置,然后重新启动:

可以看到,eureka-client从config-server获取配置信息。访问:http://localhost:8089/feign/hello?token=token,可以正常返回:

8084:hello world, null

也可以把配置放到github上,然后,config-server从github获取,修改config-server的application.yml配置文件,如下:

spring:
#  profiles:
#    active: native
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/191720653/springcloud-config
          search-paths: config
      label: master
server:
  port: 8090
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/

注释掉spring.profiles.active=native,让config-server从github上获取配置文件。

重新启动所有服务,查看日志:

可以看到,zipkin-server是从github上获取配置的。

九、完整代码

https://github.com/191720653/springcloud

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值