一个C#开发者学习SpringCloud搭建微服务的心路历程
前言
Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘。
SpringCloud是封装了Netflix公司开发的Eureka模块来实现服务注册和发现。下图为Spring Cloud Eureka的本版列表:

下图为Spring Cloud 微服务的各个实现的总览。

创建父项目
首先,我们打开IEDA创建项目,然后选择Maven选项,然后点击下一步,如下图:

创建完成后,是一个空的Java父项目,如下图:

创建服务查询中心子项目——EurekaServer
EurekaServer是用于服务查询的,C#开发者可能更熟悉consul,虽然用法不一样,但实现的效果是一样的。
现在我们创建一个服务查询中心项目,在项目上右键-->new-->Module-->Spring Initializr-->next,选择和父类项目同一版本的jdk,如下图:

然后选择SpringCloudDiscovery—EurekaServer,如下图:

创建完成如下图所示:

打开新建的项目的入口文件——EurekaserverApplication,为EurekaserverApplication类增加注解@EnableEurekaServer,这个注解会将当前类标记为Eureka Server。

然后修改application.properties为application.yml,编写代码如下:
# 配置启动端口
server:
port: 5180
# 配置eureka
eureka:
instance:
hostname: localhost
client:
fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false
register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.
service-url:
# 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址.默认是http://localhost:8761/eureka/;多个地址可使用','风格.
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
可以看到,上面的配置eureka的hostname是localhost,这个是属于服务器端的配置,但还配置了client,里面配置的内容是不把自己作为服务注册到Eureka Server服务查询中,这个配置会让我们看不懂,为什么服务器查询要配置是否把自己注册进服务查询呢?这样配置的确有点奇怪,调查发现,eureka中的服务端也是个客户端,这样做的目的是为了让服务端也可以互相注册,实现高可用,但这样的配置模式,确实很容易让人误解,不过既然已经使用了eureka,我们只能死记硬背了。
PS:具体可以搜索org.springframework.cloud.netflix.eureka. EurekaClientConfigBean来查找相关属性如何配置。
配置好EurekaServer后,我们使用IDEA调试项目,然后在浏览器输入:http://localhost:5180/,EurekaServer运行成功,如下图:

创建普通服务并注册到服务查询中心——EurekaClient
下面我们创建一个WebApi,一个使用了EurekaClient的WebApi,项目会通过EurekaClient 将当前项目注册到服务查询中心里,如下个图:

点击下一步,然后这次我们选择SpringCloudDiscovery—Eureka Discovery Client,如下图:

项目创建成功后,然后我们还是找到入口文件,为KibaApplication类加上@EnableEurekaClient注解,如下图:

然后修改application.properties为application.yml,编写代码如下:
# 启动端口
server:
port: 5181
spring:
application:
name: eureka-kiba
# eureka客户端配置,配置要注册的服务查询中心
eureka:
client:
service-url:
defaultZone: http://localhost:5180/eureka # 指定服务注册中心
然后我们在pom.xml里添加spring-boot-starter-web的Jar包引用,代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后创建一个controller文件,再创建一个HelloWorld的java类,如下图:

然后编辑HelloWorld类,代码如下:
package com.client.kiba.controller;
import org.springframework.web.bind.annotation.*;
@RequestMapping(value = "/helloWorld")
@RestController
public class HelloWorld {
@RequestMapping(value = "/GetName", method = RequestMethod.GET)
public String GetName()
{
return "我是Kiba518";
}
@RequestMapping(value = "/GetAge", method = {RequestMethod.GET,RequestMethod.POST})
public int GetAge()
{
return 518;
}
@PostMapping("/GetAge1")
public int GetAge1()
{
return 518;
}
@GetMapping("/GetAge2")
public int GetAge2()
{
return 518;
}
}
然后启动项目,然后在打开我们的eureka服务查询中心——http://localhost:5180/,可以看到服务已经成功注册进了服务中心。

注意:这里需要单独启动一下我们刚刚建好的项目。

到此,eureka服务注册就介绍完了。
不得不说,eureka把服务注册处理的如此简单,仅仅用配置就搞定了,实在非常优秀。
使用eureka内注册的服务
创建一个新moudle,创建过程如上。
修改Kiba3Application的代码如下:
package com.clinet.kiba3;
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;
@SpringBootApplication
@EnableDiscoveryClient
public class Kiba3Application {
public static void main(String[] args) {
SpringApplication.run(Kiba3Application.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate()
{
return new RestTemplate();
}
}
然后创建RemoteController接口,代码如下:
package com.clinet.kiba3.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/Remote")
public class RemoteController {
@Autowired
RestTemplate restTemplate;
/**
* http://localhost:5183/Remote/TestRestRequest
* @return
*/
@GetMapping("/TestRestRequest")
public ResponseEntity<String> TestRestRequest() {
/**
* 第一个参数:url——http://eureka-kiba2/helloWorld/GetName 这里把ip替换为在eureka中注册的名字
* 第二个参数:返回值类型
*/
ResponseEntity<String> entity = restTemplate.getForEntity("http://eureka-kiba2/helloWorld/GetName", String.class);
System.out.println("状态码:" + entity.getStatusCode());
System.out.println("响应体" + entity.getBody());
return ResponseEntity.ok(entity.getBody());
}
}
如上所示,远程调用使用的是RestTemplate,不过调用的URL稍微做了修改,如上所示,我们请求的url地址是【http://eureka-kiba2/helloWorld/GetName】,可以看到,我们将ip替换为了在eureka中注册的应用名了。
在其他的注册中心中,比如consul,也是通过应用名来调用单体服务的,这种调用模式属于潜规则了。
下图为各个单体服务在注册中心注册的应用名。

在网页输入http://localhost:5183/Remote/TestRestRequest,输出结果如下图:


PS:Eureka还可以通过配置实现负载均衡,因为注册到注册中心的服务,使用【协议+应用名+controller】的模式请求,所以将同一个服务发布到不同服务器, 调用时,因为应用名相同,就可以进行请求分流了,进而实现负载均衡了。
网关
网关的作用主要是将请求重新分发。现在我们新建一个项目用于做网关。
与上文一样,在项目上右键-->new-->Module-->Spring Initializr。
然后在选择依赖jar包时,选择Spring Cloud Routing——Getway,如下图:

在Eureka中,网关也是要作为客户端注册进注册中心的。
也就是说,我们必须引用eureka-client,如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
还要在启动类上增加@EnableEurekaClient注解,如下:
@EnableEurekaClient
@SpringBootApplication
public class GetwayApplication {
public static void main(String[] args) {
SpringApplication.run(GetwayApplication.class, args);
}
}
然后,我们配置Getway中最复杂的内容,application.yml配置。
详细配置如下:
server:
port: 5184
spring:
application:
name: getway
cloud:
gateway:
discovery:
# locator需要打开,不然通过 lb://.. 方式请求不到
locator:
enabled: true #开启 Gateway 服务注册中心服务发现
routes:
- id: kiba1 # 路由的id,要求唯一,通常使用应用名
uri: lb://eureka-kiba #lb是一个动态路由协议,后面的eureka-kiba 是要跳转的服务名称。
predicates:
- Path=/kiba1/helloWorld/** # 指定匹配的controller,也可以指定到方法,比如 - Path=/helloWorld/GetName/** 这里kiba1会在下面被过滤掉,即请求的是lb://eureka-kiba/helloworld
filters:
- StripPrefix=1 #过滤掉一个请求前缀
# JwtAuthorization
- id: kiba2
uri: lb://eureka-kiba2
predicates:
- Path=/kiba2/helloWorld_kiba2/**
filters:
- StripPrefix=1 eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:5180/eureka #注册中心地址
# healthcheck:
# enabled: true
请求注册中心的服务采用【协议+应用名+controller】的模式,但在Getway里,需要把协议从http改为了lb,才能请求注册中心的服务,开启lb协议需要配置locator的enable为true。
应用名就是在注册中心注册的应用名,
routes:指定下面就是配置路由的配置模块。
id:路由的id,要求唯一,通常使用应用名。
predicates:断言,就是判断请求是否符合条件,符合条件方可请求,即使用一些已经定义好的配置条件过滤。
predicates—Path:指定匹配的controller,也可以指定到方法,比如 - Path=/helloWorld/**,这样配置的话就是要求,请求url格式必须为http://localhost:5184/helloWorld,不然就请求失败。
filters:过滤,可以过滤请求信息,这里只用到了过滤路由的路径。
filters—StripPrefix:过滤掉请求地址总的路径,每个【/】分割一对路径,这个功能非常有用,因为配置路径时,通常会加上前缀来区分服务,这个过滤可以过滤掉前缀。
配置完成后启动项目,访问如下地址,结果如下:
http://localhost:5184/kiba1/helloWorld/GetName

http://localhost:5184/kiba2/helloWorld_kiba2/GetAge

如上图,我们已经实现了微服务的网关+注册中心+单体服务注册了。
结语
Java的微服务真的非常便捷,通过一篇比较好的文章即可学会,通过简单的配置,就可以搭建完成。真是微服务界的王者。
----------------------------------------------------------------------------------------------------
到此,SpringCloud搭建微服务已经介绍完了。
代码已经传到Github上了,欢迎大家下载。
Github地址:https://github.com/kiba518/kibacloud
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!
https://www.cnblogs.com/kiba/p/16738718.html

一个C#开发者学习SpringCloud搭建微服务的心路历程的更多相关文章
- springCloud搭建微服务集群+Zuul服务器端负载均衡
概述 最近研究了一下springCloud的微服务集群,主要用到了SpringCloud的服务发现和服务器端负载均衡,所有的项目都是用的springboot,可以和springCloud无缝对接. 技 ...
- 历史上最详细的SpringCloud搭建微服务的过程。(包括注册中心,服务提供者和服务消费者)
首先搭建注册中心,创建一个springboot的maven工程. 工程创建完成之后,先在资源文件中的application.properties中写配置文件. server.port= spring. ...
- Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 微服务不是泥球小单体,而是具备更加清晰职责边界的完整一体的业务功能服务.领域驱动 ...
- 【微服务】使用spring cloud搭建微服务框架,整理学习资料
写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...
- Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序
使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...
- 【译文】用Spring Cloud和Docker搭建微服务平台
by Kenny Bastani Sunday, July 12, 2015 转自:http://www.kennybastani.com/2015/07/spring-cloud-docker-mi ...
- 用SpringCloud进行微服务架构演进
在<架构师必须要知道的阿里的中台战略与微服务> 中已经阐明选择SpringCloud进行微服务架构实现中台战略,因此下面介绍SpringCloud的一些内容,SpringCloud已经出来 ...
- Spring Cloud和Docker搭建微服务平台
用Spring Cloud和Docker搭建微服务平台 This blog series will introduce you to some of the foundational concepts ...
- Spring Cloud Alibaba+Nacos搭建微服务架构
1. Spring Cloud Alibaba 简介 Spring Cloud Alibaba是阿里巴巴为分布式应用提供的一站式解决方案,能够更方便快捷地搭建分布式平台,nacos拥有着替换eu ...
随机推荐
- Azure Devops(十五) 使用Azure的私有Maven仓库
上一篇文章中,我们介绍了如何使用Azure的nuget仓库,今天我们来研究一下如何使用azure给我们提供的maven仓库. 首先,我们打开azureDevops,点击到制品界面,然后选择maven. ...
- java日常开发必备:list的四种遍历
在平时的开发过程中使用List的场景很多,你知道List的遍历有多少种方式?今天一起来梳理下List的几种遍历方式.这里以java.util.ArrayList为例来演示. 这里有一个最简单的 ...
- 议题征集令 | Apache DolphinScheduler Meetup 2021 来啦,议题征集正式开启!
点击上方 蓝字关注我们 社区的小伙伴们,经过精心筹备,我们很高兴地宣布,Apache DolphinScheduler Meetup 2021 将于 2021 年 11 月 27 日到来! 在 Mee ...
- 使用SSH连接解决git报错:fatal: unable to access 'https://github.com/xxx/xxx.github.io.git/': Proxy CONNECT aborted
TL;DRs 这个错误的原因和HTTPS的代理配置有关,使用SSH方式连接可以避免这一问题 最近git pull和push的时候总是报错 fatal: unable to access 'https: ...
- java-servlet过滤器和监听
1 过滤器 过滤器是什么?servlet规范当中定义的一种特殊的组件,用于拦截容器的调用.注:容器收到请求之后,如果有过滤器,会先调用过滤器,然后在调用servlet. 如何写一个过滤器? 写一个ja ...
- Magicodes.Pay已支持Volo Abp
Magicodes.Pay已支持Volo Abp 简介 Magicodes.Pay希望打造一个统一支付库,相关库均使用.NET标准库编写,支持.NET Framework以及.NET Core.目前已 ...
- Python入门系列(六)一篇学会python函数
函数 函数是只在调用时运行的代码块. def my_function(): print("Hello from a function") my_function() 信息可以作为参 ...
- KingbaseES 创建只读(read_only)用户
数据库版本: prod=> select version(); version --------------------------------------------------------- ...
- 新一代网络请求库:python-httpx库
目录 httpx库 一. 概述 1. 简介 2. 命令行模式 3. 快速开始 3.1 get请求 3.2 post请求 3.2.1 表单 3.2.2 文件 3.2.3 JSON 3.2.4 二进制 3 ...
- 优化器Optimal
未完成!!!!!! 神经网络的训练主要是通过优化损失函数来更新参数,而面对庞大数量的参数的更新,优化函数的设计就显得尤为重要,下面介绍一下几种常用的优化器及其演变过程: [先说明一下要用到符号的含义] ...