微服务入门&Nacos实战

一:微服务 & 微服务架构

 

1:单体架构 VS 微服务架构

1.1)从单体架构说起

一个工程对应一个归档包(war),这个war包 包含了该工程的所有功能。我们成为这 种应用为单体应用,也就是我们常说的单体架构(war包里出政权,一个war包打天下)。 具体描述: 就是在我们的一个war包中,聚集了各种功能以及资源,比如JSP JS,CSS等。而业务种包含了我们的用户模块,订单模块,支付模块等等.

1.2)单体架构图

1.3)单体架构优缺点总结

优点:

①: 架构简单明了,没有”花里胡哨“的问题需要解决。

②:开发,测试,部署简单(运维人员开心的不得了 )

缺点:

①:随着业务扩展,代码越来越复杂,代码质量参差不齐(开发人员的水平不一),会让 你每次提交代码 ,修改每一个小bug都是心惊胆战的。

②:部署慢(由于单体架构,功能复杂) 能想像下一个来自200W+代码部署的速度 (15分钟)

③:扩展成本高,根据单体架构图 假设用户模块是一个CPU密集型的模块(涉及到大量 的运算)那么我们需要替换更加牛逼的CPU,而我们的订单模块是一个IO密集模块(涉 及大量的读写磁盘),那我们需要替换更加牛逼的内存以及高效的磁盘。但是我们的单 体架构上 无法针对单个功能模块进行扩展,那么就需要替换更牛逼的CPU 更牛逼的内 存 更牛逼的磁盘 价格蹭蹭的往上涨。

④:阻碍了新技术的发展。。。。。。比如我们的web架构模块 从struts2迁移到 springboot,那么就会成为灾难性 

1.4)微服务以及微服务架构

1.4.1)微服务的定义

①:英文:https://martinfowler.com/articles/microservices.html

②: 中文:http://blog.cuicc.com/blog/2015/07/22/microservices

1.4.2)微服务核心

就是把传统的单机应用,根据业务将单机应用拆分为一个一个的服 务,彻底的解耦,每一个服务都是提供特定的功能,一个服务只做一件事,类似进程, 每个服务都能够单独部署,甚至可以拥有自己的数据库。这样的一个一个的小服务就 是 微服务.

①: 比如传统的单机电商应用,shop 里面有 订单/支付/库存/物流/积分等模块(理 解为servcie)

②:我们根据 业务模型来拆分,可以拆分为 订单服务,支付服务,库存服务,物流服 务,积分服务 ③:若不拆分的时候,我的非核心业务积分模块 出现了重大bug 导致系统内存溢出, 导致整个服务宕机. ,若拆分之后,只是说我的积分微服务不可用,我的整个系统核心功能还是能使用

1.4.3)单机架构扩展与微服务扩展

①:单机架构扩展 

②:微服务架构以及扩展 

③:微服务数据存储 

 1.4.4)微服务架构是什么?

微服务架构是一个架构风格, 提倡

①:将一个单一应用程序开发为一组小型服务.

②:每个服务运行在自己的进程中

③:服务之间通过轻量级的通信机制(http rest api)

④:每个服务都能够独立的部署

⑤:每个服务甚至可以拥有自己的数据库

1.4.5)微服务以及微服务架构的是二个完全不同的概念。

微服务强调的是服务的大小和对外提供的单一功能,而微服务架构是指把 一个一个的 微服务组合管理起来,对外提供一套完整的服务。

1.4.6)微服务的优缺点

优点:

①:每个服务足够小,足够内聚,代码更加容易理解,专注一个业务功能点(对比传统应 用,可能改几行代码 需要了解整个系统)

②: 开发简单,一个服务只干一个事情。(假如你做支付服务,你只要了解支付相关代 码就可以了)

③: 微服务能够被2-5个人的小团队开发,提高效率

④: 按需伸缩

⑤: 前后段分离, 作为java开发人员,我们只要关系后端接口的安全性以及性能,不要 去关注页面的人机交互(H5工程师)根据前后端接口协议,根据入参,返回json的回参

⑥:一个服务可用拥有自己的数据库。也可以多个服务连接同一个数据库.

缺点:

①:增加了运维人员的工作量,以前只要部署一个war包,现在可能需要部署成百上千 个war包 (k8s+docker+jenkis )

②: 服务之间相互调用,增加通信成本

③:数据一致性问题(分布式事物问题)

④:系能监控等,问题定位..........................

1.4.6)微服务的适用场景

合适

①:大型复杂的项目............(来自单体架构200W行代码的恐惧)

②:快速迭代的项目............(来自一天一版的恐惧)

③:并发高的项目................(考虑弹性伸缩扩容的恐惧)

不合适

①:业务稳定,就是修修bug ,改改数据

②:迭代周期长 发版频率 一二个月一次. 

二:Spring Cloud Alibaba

2.1)什么是SpringCloud?

https://spring.io/projects/spring-cloud spring cloud

子项目孵化器地址:https://github.com/spring-cloud-incubator 孵化成功就变为 springcloud的子项目了。 SpringCloud是程序员用来开发我们微服务的一整套技术解决方案.包含如下 服务注册发现,服务容错降级,服务网关,服务调用,服务调用负载均衡,消息等.

2.2)什么是Spring cloud Alibaba

Spring cloud Alibaba是我们SpringCloud的一个子项目,是提供微服务开发的一站式 解决方案.包含微服务开发的必要组件。

2.2.1)基于SpringCloud 符合SpringCloud标准,是阿里的微服务的解决方案.

文档:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md 主要功能描述: 

2.2.2)SpringCloud SpringCloudalibaba SpringBoot的生产版本选择

①:我们的SpringBoot版本 说明选择

1 /** 

2 其中2:表示的主版本号,表示是我们的SpringBoot第二代产品

3 其中1:表示的是次版本号,增加了一些新的功能但是主体的架构是没有变化的,是兼容的 

4 其中6:表示的是bug修复版 

5 所以2.1.6合起来就是springboot的第二代版本的第一个小版本的 第6次bug修复版本 

6 RELEASE:存在哪些取值了 ①:snapshot(开发版本) ②:M1...M2(里程碑版本,在 

7 正式版发布之前 会出几个里程碑的版本) ③:release(正式版本) 

8 **/ 

<parent>

       <groupId> org.springframework.boot</groupId>

       <artifactId>spring‐boot‐starter‐parent</artifactId>

       <version>2.1.6.RELEASE</version>

</parent>

②:Spring cloud的版本说明

第一代版本:Angle

第二代版本:Brixton

第三代版本:Camden

第四代版本:Edgware

第五代版本:Finchley

第六代版本:GreenWich

第七代版本:Hoxton

................................

这种发布的版本是 以伦敦地铁站发行地铁的站。 为什么我们的SpringCloud会以这种方式来发布版本,因为假如我们传统的 5.1.5release这种发布的而 SpringCloud会包含很多子项目的版本就会给人造成混 淆. 

SpringCloud的发布计划 https://github.com/spring-cloud/spring-cloud-release/milestones SpringCloud曾经发布的版本: https://github.com/spring-cloud/spring-cloud-release/releases

③:Springboot SpringCloud SpringCloudalibaba 的版本对应关系 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 

④:生产版本选择

a:打死不用 非稳定版本/ end-of-life(不维护)版本

b:release版本先等等(等别人去探雷)

c:推荐 SR2以后的可以放心使用. 

三:微服务注册中心Nacos入门

https://nacos.io/zh-cn/docs/what-is-nacos.html

服务的提供者 &服务的消费者是相对的概念 比如用户服务是订单服务的消费者,订单服务是用户服务的提供者。 但是对于 订单服务---->库存服务,那么订单服务就成为服务消费者。

 

3.1)无注册中心的调用的缺点。

比如现在我的用户服务是占用(User服务)8081端口的服务, 此时我的服务提供方 (order服务端口是8080)端口 我们可以通过RestTemplate 调用方式来进行调用 

 

 ResponseEntity<ProductInfo> responseEntity=
 restTemplate.getForEntity(“http://localhost:8081/selectProductInfoById/”+
 orderInfo.getProductNo(), ProductInfo.class);

缺点:

1)从上面看出的缺点就是,我们的在调用的时候,请求的Ip地址和端口是硬编码的. 若此时,服务提供方(order)服务部署的机器换了端口或者是更换了部署机器的Ip,那么 我们需要修改代码重新发布部署.

2) 假设我们的order服务压力过大,我们需要把order服务作为集群,那么意味着 order是多节点部署 比如原来的,我们只有一台服务器,现在有多台服务器,那么作为运维人员 需要在 服务消费方进行手工维护一份注册表(容易出错)

3)有人马上回驳我说,我可以通过ng来做负载均衡,对,我首先认为这是可行的,当时 微服务成百上千的服务,难道我们要那成百上千 ng么?或者使用一个Ng 那么我们能想一下哪个ng的配置文件有多么复杂。

3.2)大话 服务注册发现原理

V1架构图: 

3.2.1) V1版本的架构,存在以下几个问题

①:我们的微服务每次调用,都会去进行对数据库的查询,并发一高,数据库性能就是一个瓶颈问题.

②:若我们的mysql挂了,那么我们所有的微服务调用都不能正常进行。

③:若mysql是正常的,库存微服务挂了,那么也不能正常的调用

V2版本架构图 

3.3)Nacos服务端搭建

下载地址:https://github.com/alibaba/Nacos/releases

 

3.3.1)linux环境启动停止:

①:把我们的Nacos包解压 tar -zxvf nacos-server-1.1.4.tar.gz 

②:cd 到我们的解压目录nacos cd nacos

 

③:进入到bin目录下 执行命令(启动单机) sh startup.sh -m standalone

 ④:检查nacos启动的端口 lsof -i:8848

⑤:访问nocas的服务端 http://ip:8848/nacos/index.html 默认的用户名密码是 nocas/nocas

⑥:停止nocas 在nocas/bin目录下 执行 sh shutdown.sh 

 3.3.2)window环境下 启动nocas server

4:Nacos client服务端的搭建 

① 加入依赖

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐nacos‐discovery</artifactId>
</dependency>

②:写注解 @EnableDiscoveryClient

@SpringBootApplication
 @EnableDiscoveryClient
 public class Tulingvip01MsAlibabaNacosClientOrderApplication {

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

③:写配置文件 **注意**server-addr:不需要写协议

spring:
    cloud:
     nacos:
      discovery:
       server‐addr: localhost:8848
application:
 name: order‐center

④:验证我们的order-center注册到我们的nacos上 

@Autowired
private DiscoveryClient discoveryClient;

@GetMapping("/getServiceList")
public List<ServiceInstance> getServiceList() {
 List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("order‐center");
 return serviceInstanceList;
}

5:Nacos 领域模型划分以及概念详解 

 

 5.1)NameSpace(默认的NameSpace是”public“ NameSpace可以进行资源隔 离,比如我们dev环境下的NameSpace下的服务是调用不到prod的NameSpace下 的微服务)

证明1)我们dev环境下的order-center 调用 prod环境下的product-center 

①:order-center所在的namespace为dev

spring:
	cloud:
		nacos:
			discovery:
			server‐addr: localhost:8848
			#dev环境的
			namespace: bc7613d2‐2e22‐4292‐a748‐48b78170f14c #指定namespace的id
    application:
        name: order‐center

②:product-center所在的namespace 为prod

spring:
	cloud:
		nacos:
			discovery:
			server‐addr: localhost:8848
			#prod环境的
			namespace: 20989a73‐cdb3‐41b8‐85c0‐e9a3530e28a6 #指定namespace的id
    application:
        name: order‐center

③:测试调用: http://localhost:8080/selectOrderInfoById/1

5.2) Nacos的集群模式

5.2.1)首先 我们需要安装我们的ng 

http://nginx.org/download/nginx-1.14.2.tar.gz

第一步:下载ng (如:路径是/usr/local/software)

wget http://nginx.org/download/nginx-1.14.2.tar.gz

第二步:解压ng tar -xzvf nginx-1.14.2.tar.gz 得到解压目录

 

第三步: 进入解压目录 cd nginx­1.14.2

 

第四步: 执行命令指定安装目录 

/configure ­­prefix=/usr/local/nginx­1.14.2 意思是告诉等会安装的文件要放在哪里

第五步: 接下来通过命令 make 编译

执行 make命令

第六步:执行 make install 命令

 第七步:还记得第四步我们安装ng的目录么? /usr/local/nginx­1.14.2

进入该目录下的配置目录conf

第八步:修改ng的conf文件

 

修改的内容为:

修改的内容为:
upstream nacos_cluster {
server 192.168.159.8:8849;
server 192.168.159.8:8850;
server 192.168.159.8:8851;
}
server {
listen 8847;
server_name localhost;

 #charset koi8‐r;

 #access_log logs/host.access.log main;

 location /nacos/ {
 proxy_pass http://nacos_cluster/nacos/;
 }
 }


 ng配置到此完成。

 5.2.2)安装 我们的nacos­server(搭建三个集群端口分别为8849 ,8850,8851)

我们以配置一台为例(8849)为例

第一步:修改nacos8849/conf文件 application.properties

 spring.datasource.platform=mysql
 # 数据库实例数量
 db.num=1
 //自己数据库的连接信息
 db.url.0=jdbc:mysql://192.168.159.8:3306/nacos_test?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
 db.user=root
 db.password=Zw726515@

第二步:修改nacos8849/conf文件 把原来的cluster.conf.example改为 cluster.conf文件

文件内容为如下

 

到此为止 nacos8849安装完成了 nacos8850 nacos8851同样安装.

5.2.3)最后一步:创建一个数据库(需要自己创建一个数据库) 脚本的位子在 nacos/conf/nacosmysql.sql 5.2.4)需要修改nacos-server的 启动脚本jvm参数 (怕你们内存参数设置的过小启动不了这么多服务) 

 

 5.2.4)分别启动 8849 8850 8851 进入到 nacos的目录下的bin目录

执行./start.sh

启动成功的依据 查看日志 /usr/local/spring-cloud-alibaba/nacos/nacos8850/logs/start.out 

测试:

分别登陆地址:

http://192.168.159.8:8849/nacos

http://192.168.159.8:8850/nacos

http://192.168.159.8:8851/nacos

NG测试

http://192.168.159.8:8847 

 

客户端地址: 直接填写8847ng的地址就可以了 

 6.什么是配置管理??

上图缺点:

所有的环境的配置都是明文的 被太多开发人员都知道了。 业务场景:张三开发了一个新功能,业务需要,保留原来老逻辑的代码,所有他抽取了一个开关变量 isNewBusi来控制,突然新功能上了生产后,发现有bug,怎么做到修改isNewBusi的值不需要重启。

根据上图我们知道配置管理的作用可以主要总结如下

1)不同环境不管配置

2) 配置属性动态刷新

引入配置中心 

根据这幅图,我们微服务需要解决的问题

1)我微服务怎么知道配置中心的地址

2) 我微服务到底需要连接哪个环境

3)怎么找到nacos config上的对于的配置文件

微服务接入配置中心的步骤

①:添加依赖包spring-cloud-alibaba-nacos-config 

<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring‐cloud‐alibaba‐nacos‐config</artifactId>
</dependency>

②:编写配置文件,需要写一个bootstrap.yml配置文件

配置解释:

server-addr: localhost:8848 表示我微服务怎么去找我的配置中心

spring.application.name=order-center 表示当前微服务需要向配置中心索要order-center 的配置

spring.profiles.active=prod 表示我需要向配置中心索要order-center的生产环境的配置 索要文件的格式为 ${application.name}- ${spring.profiles.active}.${file-extension} 真正在nacos配置中心上 就是 order-center-prod.yml

spring:
	cloud:
		nacos:
			config:
			server‐addr: localhost:8848
			file‐extension: yml
	application:
		name: order‐center
	profiles:
	 active: prod

现在我们需要不停机改变我们的生产环境isNewBusi的值来控制我们的业务逻辑。我们需要在对应的Controller 上添加一@RefreshScope 进行动态刷新

6.2)怎么解决 生产环境,测试环境,开发环境相同的配置。(配置通用) 

比如我们的servlet-context 为order-center 查看工程启动日志

 

所以我们需要创建一个通用配置文件:order-center.yml配置 那么order-center.yml就是一个通用配置了,不管是启动prod,还是dev 都会有该段配置order-server的 context-path 配置

 

配置的优先级 精准配置 会覆盖 与通用配置 相同的配置,然后再和通用配置互补。

 

6.3)不同微服务的通用配置。

 

 6.3.1)通过 shared-dataids 方式

比如 每一个微服务都要写服务注册地址等

 spring:
	 cloud:
		 nacos:
		 discovery:
			server‐addr: localhost:8848

我们就可以把该配置提取为一个公共配置yml,提供给所有的工程使用

spring:
	cloud:
		nacos:
			config:
				server‐addr: localhost:8848
				file‐extension: yml
				#各个微服务共享的配置,注意越拍到后面的公共配置yml优先级越高
				shared‐dataids: common.yml,common2.yml
				#支持动态刷新的配置文件
				 refreshable‐dataids: common.yml,common2.yml
	 application:
	 name: order‐center
	 profiles:
	 active: dev

配置优先级 2020-01-09 21:21:19.115 INFO 15316 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[

NacosPropertySource {name='order-center-dev.yml'},

NacosPropertySource {name='order-center.yml'},

NacosPropertySource {name='common2.yml'},

NacosPropertySource {name='common.yml'} ] }

6.3.1)通过 ext-config方式

同样配置到越后面的配置 优先级越高

spring:
	cloud:
		nacos:
			config:
			server‐addr: localhost:8848
			file‐extension: yml
			ext‐config:
			- data‐id: common3.yml
			group: DEFAULT_GROUP
			 refresh: true
			 - data‐id: common4.yml
			 group: DEFAULT_GROUP
			 refresh: true

6.3.3)各个配置的优先级

精准配置>不同环境的通用配置>不同工程的(ext-config)>不同工程(shared- dataids)

spring:
  cloud:
      nacos:
          config:
          server‐addr: localhost:8848
          file‐extension: yml
          shared‐dataids: common.yml,common2.yml
          refreshable‐dataids: common.yml,common2.yml
          ext-config:
           - data‐id: common3.yml
           group: DEFAULT_GROUP
           refresh: true
           - data‐id: common4.yml
           group: DEFAULT_GROUP
           refresh: true
  
   application:
   name: order‐center
   profiles:
   active: dev

上述配置 加载的优先级

1)order-center-dev.yml 精准配置

2)order-center.yml 同工程不同环境的通用配置

3)ext-config: 不同工程 通用配置

  3.1):common4.yml

  3.2): common3.yml

4) shared-dataids 不同工程通用配置

  4.1)common2.yml

  4.2)common1.yml 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小强同志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值