谷粒商城—分布式基础

1. 整体介绍

在这里插入图片描述

1)安装vagrant

2)安装Centos7

$ vagrant init centos/7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

执行完上面的命令后,会在用户的家目录下生成Vagrantfile文件。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'centos/7' could not be found. Attempting to find and install...default: Box Provider: virtualboxdefault: Box Version: >= 0
==> default: Loading metadata for box 'centos/7'default: URL: https://vagrantcloud.com/centos/7
==> default: Adding box 'centos/7' (v1905.1) for provider: virtualboxdefault: Downloading: https://vagrantcloud.com/centos/boxes/7/versions/1905.1/providers/virtualbox.boxdefault: Download redirected to host: cloud.centos.orgdefault: Progress: 0% (Rate: 6717/s, Estimated time remaining: 7:33:42)

下载镜像过程比较漫长,也可以采用先用下载工具下载到本地后,然后使用“ vagrant box add ”添加,再“vagrant up”即可

#将下载的镜像添加到virtualBox中
$ vagrant box add centos/7 E:\迅雷下载\CentOS-7-x86_64-Vagrant-1905_01.VirtualBox.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos/7' (v0) for provider:box: Unpacking necessary files from: file:///E:/%D1%B8%C0%D7%CF%C2%D4%D8/CentOS-7-x86_64-Vagrant-1905_01.VirtualBox.boxbox:
==> box: Successfully added box 'centos/7' (v0) for 'virtualbox'!#启动
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos/7'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: Administrator_default_1588497928070_24634
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...default: Adapter 1: natdefault: Adapter 2: hostonly
==> default: Forwarding ports...default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...default: SSH address: 127.0.0.1:2222default: SSH username: vagrantdefault: SSH auth method: private keydefault:default: Vagrant insecure key detected. Vagrant will automatically replacedefault: this with a newly generated keypair for better security.default:default: Inserting generated public key within guest...default: Removing insecure key from the guest if it's present...default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...default: No guest additions were detected on the base box for this VM! Guestdefault: additions are required for forwarded ports, shared folders, host onlydefault: networking, and more. If SSH fails on this machine, please installdefault: the guest additions and repackage the box to continue.default:default: This is not an error message; everything may continue to work properly,default: in which case you may ignore this message.
==> default: Configuring and enabling network interfaces...
==> default: Rsyncing folder: /cygdrive/c/Users/Administrator/ => /vagrant

vagrant ssh 开启SSH,并登陆到centos7

$ vagrant ssh
[vagrant@localhost ~]$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 52:54:00:8a:fe:e6 brd ff:ff:ff:ff:ff:ffinet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0valid_lft 86091sec preferred_lft 86091secinet6 fe80::5054:ff:fe8a:fee6/64 scope linkvalid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 08:00:27:d1:76:f6 brd ff:ff:ff:ff:ff:ffinet 192.168.56.102/24 brd 192.168.56.255 scope global noprefixroute dynamic eth1valid_lft 892sec preferred_lft 892secinet6 fe80::8c94:1942:ba09:2458/64 scope link noprefixroutevalid_lft forever preferred_lft forever
[vagrant@localhost ~]$
C:\Users\Administrator>ipconfigWindows IP 配置以太网适配器 VirtualBox Host-Only Network:连接特定的 DNS 后缀 . . . . . . . :本地链接 IPv6 地址. . . . . . . . : fe80::a00c:1ffa:a39a:c8c2%16IPv4 地址 . . . . . . . . . . . . : 192.168.56.1子网掩码  . . . . . . . . . . . . : 255.255.255.0默认网关. . . . . . . . . . . . . :

配置网络信息,打开"Vagrantfile"文件:

config.vm.network "private_network", ip: "192.168.56.10"

修改完成后,重启启动vagrant

vagrant reload

检查宿主机和virtualBox之间的通信是否正常

[vagrant@localhost ~]$ ping 192.168.43.43                                                                                                         PING 192.168.43.43 (192.168.43.43) 56(84) bytes of data.
64 bytes from 192.168.43.43: icmp_seq=1 ttl=127 time=0.533 ms
64 bytes from 192.168.43.43: icmp_seq=2 ttl=127 time=0.659 ms--- 192.168.43.43 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.533/0.596/0.659/0.063 ms
[vagrant@localhost ~]$
[vagrant@localhost ~]$
[vagrant@localhost ~]$ ping www.baidu.com
PING www.a.shifen.com (112.80.248.76) 56(84) bytes of data.
64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=1 ttl=53 time=56.1 ms
64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=2 ttl=53 time=58.5 ms
64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=3 ttl=53 time=53.4 ms

开启远程登陆,修改“/etc/ssh/sshd_config”

PermitRootLogin yes 
PasswordAuthentication yes

然后重启SSHD

systemctl restart sshd

使用Xshell或SecureCRT进行远程连接。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=images%2Fimage-20200503174735162.png&pos_id=img-916KZC8Q-1733973795795

在这里插入图片描述

2. docker中安装mysql

[root@hadoop-104 module]# docker pull mysql:5.7
5.7: Pulling from library/mysql
123275d6e508: Already exists 
27cddf5c7140: Pull complete 
c17d442e14c9: Pull complete 
2eb72ffed068: Pull complete 
d4aa125eb616: Pull complete 
52560afb169c: Pull complete 
68190f37a1d2: Pull complete 
3fd1dc6e2990: Pull complete 
85a79b83df29: Pull complete 
35e0b437fe88: Pull complete 
992f6a10268c: Pull complete 
Digest: sha256:82b72085b2fcff073a6616b84c7c3bcbb36e2d13af838cec11a9ed1d0b183f5e
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

查看镜像

[root@hadoop-104 module]# docker images
REPOSITORY  TAG    IMAGE ID     CREATED       SIZE
mysql       5.7    f5829c0eee9e 2 hours ago   455MB
[root@hadoop-104 module]# 

启动mysql

sudo docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7

修改配置

[root@hadoop-104 conf]# pwd
/mydata/mysql/conf[root@hadoop-104 conf]# cat my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
[root@hadoop-104 conf]# [root@hadoop-104 conf]# docker restart mysql
mysql
[root@hadoop-104 conf]# 

进入容器查看配置:

[root@hadoop-104 conf]# docker exec -it mysql /bin/bash
root@b3a74e031bd7:/# whereis mysql
mysql: /usr/bin/mysql /usr/lib/mysql /etc/mysql /usr/share/mysqlroot@b3a74e031bd7:/# ls /etc/mysql 
my.cnf
root@b3a74e031bd7:/# cat /etc/mysql/my.cnf 
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
root@b3a74e031bd7:/# 

设置启动docker时,即运行mysql

[root@hadoop-104 ~]# docker update mysql --restart=always
mysql
[root@hadoop-104 ~]# 

3. docker中安装redis

下载docker

[root@hadoop-104 ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
123275d6e508: Already exists 
f2edbd6a658e: Pull complete 
66960bede47c: Pull complete 
79dc0b596c90: Pull complete 
de36df38e0b6: Pull complete 
602cd484ff92: Pull complete 
Digest: sha256:1d0b903e3770c2c3c79961b73a53e963f4fd4b2674c2c4911472e8a054cb5728
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

启动docker

[root@hadoop-104 ~]# mkdir -p /mydata/redis/conf
[root@hadoop-104 ~]# touch /mydata/redis/conf/redis.conf
[root@hadoop-104 ~]# echo "appendonly yes"  >> /mydata/redis/conf/redis.conf
[root@hadoop-104 ~]# docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
> -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
> -d redis redis-server /etc/redis/redis.conf
ce7ae709711986e3f90c9278b284fe6f51f1c1102ba05f3692f0e934ceca1565
[root@hadoop-104 ~]# 

连接到docker的redis

[root@hadoop-104 ~]# docker exec -it redis redis-cli
127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> 

设置redis容器在docker启动的时候启动

[root@hadoop-104 ~]# docker update redis --restart=always
redis
[root@hadoop-104 ~]# 

4. 创建maven工程

5. 执行sql脚本

gulimall_oms.sql
gulimall_pms.sql
gulimall_sms.sql
gulimall_ums.sql
gulimall_wms.sql
pms_catelog.sql
sys_menus.sql

6. clone 人人开源

https://gitee.com/renrenio

在这里插入图片描述

克隆到本地:

git clone https://gitee.com/renrenio/renren-fast-vue.gitgit clone https://gitee.com/renrenio/renren-fast.git

将拷贝下来的“renren-fast”删除“.git”后,拷贝到“gulimall”工程根目录下,然后将它作为gulimall的一个module

创建“gulimall_admin”的数据库,然后执行“renren-fast/db/mysql.sql”中的SQl脚本

修改“application-dev.yml”文件,默认为dev环境,修改连接mysql的url和用户名密码

spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.137.14:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: root

启动“gulimall_admin”,然后访问“http://localhost:8080/renren-fast/”

在这里插入图片描述

安装node.js,并且安装仓库

npm config set registry http://registry.npm.taobao.org/
PS D:\tmp\renren-fast-vue> npm config set registry http://registry.npm.taobao.org/
PS D:\tmp\renren-fast-vue> npm install
npm WARN ajv-keywords@1.5.1 requires a peer of ajv@>=4.10.0 but none is installed. You must install peer dependencies yourself.
npm WARN sass-loader@6.0.6 requires a peer of node-sass@^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})up to date in 17.227s
PS D:\tmp\renren-fast-vue> 
PS D:\tmp\renren-fast-vue> npm run dev> renren-fast-vue@1.2.2 dev D:\tmp\renren-fast-vue
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js10% building modules 5/10 modules 5 active ...-0!D:\tmp\renren-fast-vue\src\main.js(node:19864) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:19864) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'dirs' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'pushd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'popd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'echo' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'tempdir' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'pwd' of module exports inside circular dependency

常见问题1:“Module build failed: Error: Cannot find module 'node-sass”

运行过程中,出现“Module build failed: Error: Cannot find module 'node-sass’报错问题”,解决方法

用npm install -g cnpm --registry=https://registry.npm.taobao.org ,从淘宝镜像那下载,然后cnpm下载成功。

最后输入cnpm install node-sass --save。npm run dev终于能跑起来了!!!

常见问题2:cnpm - 解决 " cnpm : 无法加载文件 C:\Users\93457\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息 。。。 "

https://www.cnblogs.com/500m/p/11634969.html

所有问题的根源都在“node_modules”,npm install之前,应该将这个文件夹删除,然后再进行安装和运行。

再次运行npm run dev恢复正常:

在这里插入图片描述

7. clone renren-generator

clone

https://gitee.com/renrenio/renren-generator.git

然后将该项目放置到“gulimall”的跟路径下,然后添加该Module,并且提交到github上

修改配置

renren-generator/src/main/resources/generator.properties

#代码生成器,配置信息mainPath=com.bigdata
#包名
package=com.bigdata.gulimall
moduleName=product
#作者
author=cosmoswong
#Email
email=cosmoswong@sina.com
#表前缀(类名不会包含表前缀)
tablePrefix=pms_

运行“renren-generator”

访问:<http://localhost:80/

在这里插入图片描述

点击“renren-fast”,能够看到它将“renren-fast”的所有表都列举了出来:

在这里插入图片描述

选择所有的表,然后点击“生成代码”,将下载的“renren.zip”,解压后取出main文件夹,放置到“gulimall-product”项目的main目录中。

下面的几个module,也采用同样的方式来操作。

但是针对于“undo_log”,存在一个问题

在这里插入图片描述

它的数据类型是“longblob”类型,逆向工程后,对应的数据类型未知:

在这里插入图片描述

这个问题该要怎么解决?

整合mybatis-plus

1)、导入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.2.0</version></dependency>

2)、配置

1、配置数据源;

1)、导入数据库的驱动。https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html

2)、在application.yml配置数据源相关信息

spring:datasource:username: rootpassword: rooturl: jdbc:mysql://#:3306/gulimall_pmsdriver-class-name: com.mysql.cj.jdbc.Driver

2、配置MyBatis-Plus;

1)、使用@MapperScan

2)、告诉MyBatis-Plus,sql映射文件位置

mybatis-plus:mapper-locations: classpath:/mapper/**/*.xmlglobal-config:db-config:#主键自增id-type: auto

8. 微服务注册中心

要注意nacos集群所在的server,一定要关闭防火墙,否则容易出现各种问题。

搭建nacos集群,然后分别启动各个微服务,将它们注册到Nacos中。

  application:name: gulimall-couponcloud:nacos:discovery:server-addr: 192.168.137.14

查看注册情况:

http://192.168.137.14:8848/nacos/#/serviceManagement?dataId=&group=&appName=&namespace=

在这里插入图片描述

9. 使用openfen

1)、引入open-feign

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

2)、编写一个接口,告诉SpringCLoud这个接口需要调用远程服务

修改“io.niceseason.gulimall.coupon.controller.CouponController”,添加以下controller方法:

    @RequestMapping("/member/list")public R memberCoupons(){CouponEntity couponEntity = new CouponEntity();couponEntity.setCouponName("discount 20%");return R.ok().put("coupons",Arrays.asList(couponEntity));}

新建“io.niceseason.gulimall.member.feign.CouponFeignService”接口

@FeignClient("gulimall_coupon")
public interface CouponFeignService {@RequestMapping("/coupon/coupon/member/list")public R memberCoupons();
}

修改“io.niceseason.gulimall.member.GulimallMemberApplication”类,添加上"@EnableFeignClients":

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "io.niceseason.gulimall.member.feign")
public class GulimallMemberApplication {public static void main(String[] args) {SpringApplication.run(GulimallMemberApplication.class, args);}
}

​ 声明接口的每一个方法都是调用哪个远程服务的那个请求

3)、开启远程调用功能

io.niceseason.gulimall.member.controller.MemberController

    @RequestMapping("/coupons")public R test(){MemberEntity memberEntity=new MemberEntity();memberEntity.setNickname("zhangsan");R memberCoupons = couponFeignService.memberCoupons();return memberCoupons.put("member",memberEntity).put("coupons",memberCoupons.get("coupons"));}

(4)、访问http://localhost:8000/member/member/coupons

在这里插入图片描述

停止“gulimall-coupon”服务,能够看到注册中心显示该服务的健康值为0:

在这里插入图片描述

再次访问:http://localhost:8000/member/member/coupons

在这里插入图片描述

启动“gulimall-coupon”服务,再次访问,又恢复了正常。

10. 配置中心

1)修改“gulimall-coupon”模块

添加pom依赖:

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

创建bootstrap.properties文件,该配置文件会优先于“application.yml”加载。

spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=192.168.137.14:8848

2)传统方式

为了详细说明config的使用方法,先来看原始的方式

创建“application.properties”配置文件,添加如下配置内容:

coupon.user.name="zhangsan"
coupon.user.age=30

修改“io.niceseason.gulimall.coupon.controller.CouponController”文件,添加如下内容:

    @Value("${coupon.user.name}")private String name;@Value("${coupon.user.age}")private Integer age;@RequestMapping("/test")public R getConfigInfo(){return R.ok().put("name",name).put("age",age);}

启动“gulimall-coupon”服务:

访问:http://localhost:7000/coupon/coupon/test>

在这里插入图片描述

这样做存在的一个问题,如果频繁的修改application.properties,在需要频繁重新打包部署。下面我们将采用Nacos的配置中心来解决这个问题。

3)nacos config

1、在Nacos注册中心中,点击“配置列表”,添加配置规则:

在这里插入图片描述

DataID:gulimall-coupon

配置格式:properties

文件的命名规则为: s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name{spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

${spring.application.name}:为微服务名

${spring.profiles.active}:指明是哪种环境下的配置,如dev、test或info

${spring.cloud.nacos.config.file-extension}:配置文件的扩展名,可以为properties、yml等

2、查看配置:

在这里插入图片描述

3、修改“io.niceseason.gulimall.coupon.controller.CouponController”类,添加“@RefreshScope”注解

@RestController
@RequestMapping("coupon/coupon")
@RefreshScope
public class CouponController {

这样都会动态的从配置中心读取配置.

4、访问:http://localhost:7000/coupon/coupon/test

能够看到读取到了nacos 中的最新的配置信息,并且在指明了相同的配置信息时,配置中心中设置的值优先于本地配置。

4)Nacos支持三种配置加载方方案

Nacos支持“Namespace+group+data ID”的配置解决方案。

详情见:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc

Namespace方案

通过命名空间实现环境区分

下面是配置实例:

1、创建命名空间:

“命名空间”—>“创建命名空间”:

在这里插入图片描述

创建三个命名空间,分别为dev,test和prop

2、回到配置列表中,能够看到所创建的三个命名空间

在这里插入图片描述

下面我们需要在dev命名空间下,创建“gulimall-coupon.properties”配置规则:

在这里插入图片描述

3、访问:http://localhost:7000/coupon/coupon/test

在这里插入图片描述

并没有使用我们在dev命名空间下所配置的规则,而是使用的是public命名空间下所配置的规则,这是怎么回事呢?

查看“gulimall-coupon”服务的启动日志:

2020-04-24 16:37:24.158  WARN 32792 --- [           main] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[gulimall-coupon] & group[DEFAULT_GROUP]
2020-04-24 16:37:24.163  INFO 32792 --- [           main] c.a.nacos.client.config.utils.JVMUtil    : isMultiInstance:false
2020-04-24 16:37:24.169  INFO 32792 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-gulimall-coupon.properties,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-gulimall-coupon,DEFAULT_GROUP'}]

“gulimall-coupon.properties”,默认就是public命名空间中的内容中所配置的规则。

4、指定命名空间

如果想要使得我们自定义的命名空间生效,需要在“bootstrap.properties”文件中,指定使用哪个命名空间:

spring.cloud.nacos.config.namespace=a2c83f0b-e0a8-40fb-9b26-1e9d61be7d6d

这个命名空间ID来源于我们在第一步所创建的命名空间

在这里插入图片描述

5、重启“gulimall-coupon”,再次访问:http://localhost:7000/coupon/coupon/test

在这里插入图片描述

但是这种命名空间的粒度还是不够细化,对此我们可以为项目的每个微服务module创建一个命名空间。

6、为所有微服务创建命名空间

在这里插入图片描述

7、回到配置列表选项卡,克隆pulic的配置规则到coupon命名空间下

在这里插入图片描述

切换到coupon命名空间下,查看所克隆的规则:

在这里插入图片描述

8、修改“gulimall-coupon”下的bootstrap.properties文件,添加如下配置信息

spring.cloud.nacos.config.namespace=7905c915-64ad-4066-8ea9-ef63918e5f79

这里指明的是,读取时使用coupon命名空间下的配置。

9、重启“gulimall-coupon”,访问:http://localhost:7000/coupon/coupon/test

在这里插入图片描述

DataID方案

通过指定spring.profile.active和配置文件的DataID,来使不同环境下读取不同的配置,读取配置时,使用的是默认命名空间public,默认分组(default_group)下的DataID。

默认情况,Namespace=public,Group=DEFAULT GROUP,默认Cluster是DEFAULT

通过制定spring.profiles.active=dev可以制定xxx-dev.properties的配置文件

Group方案

通过Group实现环境区分

实例:通过使用不同的组,来读取不同的配置,还是以上面的gulimall-coupon微服务为例

1、新建“gulimall-coupon.properties”,将它置于“tmp”组下

在这里插入图片描述

2、修改“bootstrap.properties”配置,添加如下的配置

spring.cloud.nacos.config.group=tmp

3、重启“gulimall-coupon”,访问:http://localhost:7000/coupon/coupon/test

在这里插入图片描述

5)同时加载多个配置集

当微服务数量很庞大时,将所有配置都书写到一个配置文件中,显然不是太合适。对此我们可以将配置按照功能的不同,拆分为不同的配置文件。

如下面的配置文件:

server:port: 7000spring:datasource:#MySQL配置driverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.137.14:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=falseusername: rootpassword: rootapplication:name: gulimall-couponcloud:nacos:discovery:server-addr: 192.168.137.14:8848mybatis-plus:global-config:db-config:id-type: automapper-locations: classpath:/mapper/**/*.xml

我们可以将,

数据源有关的配置写到一个配置文件中:

spring:datasource:#MySQL配置driverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.137.14:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=falseusername: rootpassword: root

和框架有关的写到另外一个配置文件中:

mybatis-plus:global-config:db-config:id-type: automapper-locations: classpath:/mapper/**/*.xml

也可以将上面的这些配置交给nacos来进行管理。

实例:将“gulimall-coupon”的“application.yml”文件拆分为多个配置,并放置到nacos配置中心

1、创建“datasource.yml”,用于存储和数据源有关的配置

spring:datasource:#MySQL配置driverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.137.14:3306/gulimall_sms?useUnicode=true&characterEncoding=UTF-8&useSSL=falseusername: rootpassword: root

在coupon命名空间中,创建“datasource.yml”配置

在这里插入图片描述

2、将和mybatis相关的配置,放置到“mybatis.yml”中

mybatis-plus:global-config:db-config:id-type: automapper-locations: classpath:/mapper/**/*.xml

在这里插入图片描述

3、创建“other.yml”配置,保存其他的配置信息

server:port: 7000spring:application:name: gulimall-couponcloud:nacos:discovery:server-addr: 192.168.137.14:8848

在这里插入图片描述

现在“mybatis.yml”、“datasource.yml”和“other.yml”共同构成了微服务的配置。

4、修改“gulimall-coupon”的“bootstrap.properties”文件,加载“mybatis.yml”、“datasource.yml”和“other.yml”配置

spring.cloud.nacos.config.extension-configs[0].data-id=mybatis.yml
spring.cloud.nacos.config.extension-configs[0].group=dev
spring.cloud.nacos.config.extension-configs[0].refresh=truespring.cloud.nacos.config.extension-configs[1].data-id=datasource.yml
spring.cloud.nacos.config.extension-configs[1].group=dev
spring.cloud.nacos.config.extension-configs[1].refresh=truespring.cloud.nacos.config.extension-configs[2].data-id=other.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true

"spring.cloud.nacos.config.ext-config"已经被废弃,建议使用“spring.cloud.nacos.config.extension-configs”,根据自己的版本选择配置。

5、注释“application.yml”文件中的所有配置

6、重启“gulimall-coupon”服务,然后访问:http://localhost:7000/coupon/coupon/test

在这里插入图片描述

7、访问:http://localhost:7000/coupon/coupon/list,查看是否能够正常的访问数据库

在这里插入图片描述

小结:

1)、微服务任何配置信息,任何配置文件都可以放在配置中心;

2)、只需要在bootstrap.properties中,说明加载配置中心的哪些配置文件即可;

3)、@Value, @ConfigurationProperties。都可以用来获取配置中心中所配置的信息;

4)、配置中心有的优先使用配置中心中的,没有则使用本地的配置。

11. 网关

1、注册“gulimall-gateway”到Nacos

1)创建“gulimall-gateway”

SpringCloud gateway

2)添加“gulimall-common”依赖和“spring-cloud-starter-gateway”依赖
        <dependency><groupId>io.niceseason.gulimall</groupId><artifactId>gulimall-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>
3)“io.niceseason.gulimall.gulimallgateway.GulimallGatewayApplication”类上加上“@EnableDiscoveryClient”注解
4)在Nacos中创建“gateway”命名空间,同时在该命名空间中创建“gulimall-gateway.yml”

在这里插入图片描述

5)创建“bootstrap.properties”文件,添加如下配置,指明配置中心地址和所属命名空间
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=192.168.137.14:8848
spring.cloud.nacos.config.namespace=1c82552e-1af0-4ced-9a48-26f19c2d315f
6)创建“application.properties”文件,指定服务名和注册中心地址
spring.application.name=gulimall-gateway
spring.cloud.nacos.discovery.server-addr=192.168.137.14:8848
server.port=88
7)启动“gulimall-gateway”

启动报错:

Description:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver class

解决方法:在“io.niceseason.gulimall.gulimallgateway.GulimallGatewayApplication”中排除和数据源相关的配置

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

重新启动

访问:http://192.168.137.14:8848/nacos/#,查看到该服务已经注册到了Nacos中

在这里插入图片描述

2、案例

现在想要实现针对于“http://localhost:88/hello?url=baidu”,转发到“https://www.baidu.com”,针对于“http://localhost:88/hello?url=qq”的请求,转发到“https://www.qq.com/”

1)创建“application.yml”
spring:cloud:gateway:routes:- id: baidu_routeuri: https://www.baidu.compredicates:- Query=url, baidu- id: qq_routeuri: https://www.qq.com/predicates:- Query=url, qq
2)启动“gulimall-gateway”
3)测试

访问:http://localhost:88/hello?url=baidu

访问:http://localhost:88/hello?url=qq

Gateway官方文档

12. Vue

安装vue

# 最新稳定版
$ npm install vue

1、vue声明式渲染

let vm = new Vue({el: "#app",//绑定元素data: {  //封装数据name: "张三",num: 1},methods:{  //封装方法cancle(){this.num -- ;},hello(){return "1"}}});

2、双向绑定,模型变化,视图变化。反之亦然

双向绑定使用v-model

 <input type="text" v-model="num">
<h1> {{name}} ,非常帅,有{{num}}个人为他点赞{{hello()}}</h1>
1587746815353

3、事件处理

v-xx:指令
1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
2、指令来简化对dom的一些操作。
3、声明方法来做更复杂的操作。methods里面可以封装方法。

v-on是按钮的单击事件:

 <button v-on:click="num++">点赞</button>

在VUE中el,data和vue的作用:

  • el:用来绑定数据;
  • data:用来封装数据;
  • methods:用来封装方法,并且能够封装多个方法,如何上面封装了cancell和hello方法。

安装“Vue 2 Snippets”,用来做代码提示

在这里插入图片描述

为了方便的在浏览器上调试VUE程序,需要安装“vue-devtools”,编译后安装到chrome中即可。

详细的使用方法见:Vue调试神器vue-devtools安装

“v-html”不会对于HTML标签进行转义,而是直接在浏览器上显示data所设置的内容;而“ v-text”会对html标签进行转义

     <div id="app">{{msg}}  {{1+1}}  {{hello()}}<br/><span v-html="msg"></span><br/><span v-text="msg"></span></div><script src="../node_modules/vue/dist/vue.js"></script><script>new Vue({el:"#app",data:{msg:"<h1>Hello</h1>",link:"http://www.baidu.com"},methods:{hello(){return "World"}}})</script>

运行结果:

在这里插入图片描述

{{msg}} :称为差值表达式,它必须要写在Html表达式,可以完成数学运算和方法调用

4、v-bind :单向绑定

给html标签的属性绑定

 <!-- 给html标签的属性绑定 --><div id="app"> <a v-bind:href="link">gogogo</a><!-- class,style  {class名:加上?}--><span v-bind:class="{active:isActive,'text-danger':hasError}":style="{color: color1,fontSize: size}">你好</span></div><script src="../node_modules/vue/dist/vue.js"></script><script>let vm = new Vue({el:"#app",data:{link: "http://www.baidu.com",isActive:true,hasError:true,color1:'red',size:'36px'}})</script>

上面所完成的任务就是给a标签绑定一个超链接。并且当“isActive”和“hasError”都是true的时候,将属性动态的绑定到,则绑定该“active”和 "text-danger"class。这样可以动态的调整属性的存在。

而且如果想要实现修改vm的"color1"和“size”, span元素的style也能够随之变化,则可以写作v-bind:style,也可以省略v-bind。

5、v-model双向绑定

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><!-- 表单项,自定义组件 --><div id="app">精通的语言:<input type="checkbox" v-model="language" value="Java"> java<br/><input type="checkbox" v-model="language" value="PHP"> PHP<br/><input type="checkbox" v-model="language" value="Python"> Python<br/>选中了 {{language.join(",")}}</div><script src="../node_modules/vue/dist/vue.js"></script><script>let vm = new Vue({el:"#app",data:{language: []}})</script></body>
</html>

上面完成的功能就是通过“v-model”为输入框绑定多个值,能够实现选中的值,在data的language也在不断的发生着变化,

在这里插入图片描述

如果在控制台上指定vm.language=[“Java”,“PHP”],则data值也会跟着变化。

在这里插入图片描述

通过“v-model”实现了页面发生了变化,则数据也发生变化,数据发生变化,则页面也发生变化,这样就实现了双向绑定。

数组的连接操作: 选中了 {{language.join(“,”)}}

6、v-on为按钮绑定事件

        <!--事件中直接写js片段--><button v-on:click="num++">点赞</button><!--事件指定一个回调函数,必须是Vue实例中定义的函数--><button @click="cancle">取消</button>

上面是为两个按钮绑定了单击事件,其中一个对于num进行自增,另外一个自减。

v-on:click也可以写作@click

事件的冒泡:

        <!-- 事件修饰符 --><div style="border: 1px solid red;padding: 20px;" v-on:click="hello">大div<div style="border: 1px solid blue;padding: 20px;" @click="hello">小div <br /><a href="http://www.baidu.com" @click.prevent="hello">去百度</a></div></div>

上面的这两个嵌套div中,如果点击了内层的div,则外层的div也会被触发;这种问题可以事件修饰符来完成:

        <!-- 事件修饰符 --><div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">大div<div style="border: 1px solid blue;padding: 20px;" @click.stop="hello">小div <br /><a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a><!--这里禁止了超链接的点击跳转操作,并且只会触发当前对象的操作--></div></div>

关于事件修饰符:

在这里插入图片描述

按键修饰符:

在这里插入图片描述

在这里插入图片描述

7、v-for遍历循环

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/488942.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【考前预习】1.计算机网络概述

往期推荐 子网掩码、网络地址、广播地址、子网划分及计算-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解&#xff0c;史上最全】-CSDN博客 浅学React和JSX-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生 serverless-CSDN博客 浅谈维度建模、数据分析…

计算机视觉与医学的结合:推动医学领域研究的新机遇

目录 引言医学领域面临的发文难题计算机视觉与医学的结合&#xff1a;发展趋势计算机视觉结合医学的研究方向高区位参考文章结语 引言 计算机视觉&#xff08;Computer Vision, CV&#xff09;技术作为人工智能的重要分支&#xff0c;已经在多个领域取得了显著的应用成果&…

AI智算-k8s部署大语言模型管理工具Ollama

文章目录 简介k8s部署OllamaOpen WebUI访问Open-WebUI 简介 Github&#xff1a;https://github.com/ollama/ollama 官网&#xff1a;https://ollama.com/ API&#xff1a;https://github.com/ollama/ollama/blob/main/docs/api.md Ollama 是一个基于 Go 语言开发的可以本地运…

PyQt事件机制练习

一、思维导图 二、代码 import sysfrom PyQt6.QtTextToSpeech import QTextToSpeech from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QLineEdit from PyQt6 import uic from PyQt6.QtCore import Qt, QTimerEvent, QTimeclass MyWidget(QWidget):d…

硬件设计 | Altium Designer软件PCB规则设置

基于Altium Designer&#xff08;24.9.1&#xff09;版本 嘉立创PCB工艺加工能力范围说明-嘉立创PCB打样专业工厂-线路板打样 规则参考-嘉立创 注意事项 1.每次设置完规则参数都要点击应用保存 2.每次创建PCB&#xff0c;都要设置好参数 3.可以设置默认规则&#xff0c;将…

【计算机学习笔记】GB2312、GBK、Unicode等字符编码的理解

之前编写win32程序时没怎么关注过宽字符到底是个啥东西&#xff0c;最近在编写网络框架又遇到字符相关的问题&#xff0c;所以写一篇文章记录一下&#xff08;有些部分属于个人理解&#xff0c;如果有错误欢迎指出&#xff09; 目录 几个常见的编码方式Unicode和UTF-8、UTF-16、…

深入理解 CSS 文本换行: overflow-wrap 和 word-break

前言 正常情况下&#xff0c;在固定宽度的盒子中的中文会自动换行。但是&#xff0c;当遇到非常长的英文单词或者很长的 URL 时&#xff0c;文本可能就不会自动换行&#xff0c;而会溢出所在容器。幸运的是&#xff0c;CSS 为我们提供了一些和文本换行相关的属性&#xff1b;今…

centos9升级OpenSSH

需求 Centos9系统升级OpenSSH和OpenSSL OpenSSH升级为openssh-9.8p1 OpenSSL默认为OpenSSL-3.2.2&#xff08;根据需求进行升级&#xff09; 将源码包编译为rpm包 查看OpenSSH和OpenSSL版本 ssh -V下载源码包并上传到服务器 openssh最新版本下载地址 wget https://cdn.openb…

Pull requests 和Merge Request其实是一个意思

Pull requests的定义 在Git中&#xff0c;PR&#xff08;Pull Request&#xff09;是一种协作开发的常用方式。它允许开发者将自己的代码变更&#xff08;通常是一个分支&#xff09;提交到项目的仓库中&#xff0c;然后请求负责代码审查的人员将这些变更合并到主分支中。通过…

【ubuntu】将Chroma配置为LINUX服务

Chroma是一个轻量级向量数据库。既然是数据库&#xff0c;那么我希望它是能够长时间运行。最直接的方式是配置为service服务。 可惜官方没有去提供配置为服务的办法&#xff0c;而鄙人对docker又不是特别感冒。所以自己研究了下chroma配置为服务的方式。 系统&#xff1a;ubu…

w~深度学习~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12663254 #Motion Plan 代码 github.com/liangwq/robot_motion_planing 轨迹约束中的软硬约束 前面的几篇文章已经介绍了&#xff0c;轨迹约束的本质就是在做带约束的轨迹拟合。输入就是waypoint点list&#xff0c;约束…

机器人构建详解:售前售后服务客服机器人与广告生成机器人的微调数据处理方法

引言 大模型&#xff08;如BERT、GPT等&#xff09;在自然语言处理任务中展现了强大的能力&#xff0c;但为了使其更贴合特定应用场景&#xff0c;通常需要进行微调。本文将详细讲解如何为售前售后服务的客服机器人和广告生成机器人准备高质量的微调数据&#xff0c;并通过具体…

cocos中使用SocketIO

Creator版本&#xff1a;v3.8.3 socketIO是socket的一个封装 cocos里集成了websocket但是没有socketIO 下载依赖文件 首先需要下载socketIO代码&#xff0c;版本要和后端保持一致 能npm下载最好npm install socket.io-clientversion(需要指定版本) 但我这一直超时,所以就直接…

AWD学习(二)

学习参考&#xff1a; AWD攻防学习总结&#xff08;草稿状态&#xff0c;待陆续补充&#xff09;_awd攻防赛入门-CSDN博客国赛分区赛awd赛后总结-安心做awd混子-安全客 - 安全资讯平台 记第一次 AWD 赛前准备与赛后小结-腾讯云开发者社区-腾讯云 AWD学习笔记 - DiaosSamas Blog…

Java从入门到工作2 - IDEA

2.1、项目启动 从git获取到项目代码后&#xff0c;用idea打开。 安装依赖完成Marven/JDK等配置检查数据库配置启动相关服务 安装依赖 如果个别依赖从私服下载不了&#xff0c;可以去maven官网下载补充。 如果run时提示程序包xx不存在&#xff0c;在项目目录右键Marven->Re…

基于Qwen2-VL模型针对LaTeX OCR任务进行微调训练 - 原模型 多图推理

基于Qwen2-VL模型针对LaTeX OCR任务进行微调训练 - 原模型 多图推理 flyfish 输入 输出 [‘第一张图片是一幅中国山水画&#xff0c;描绘了一座山峰和周围的树木。第二张图片是一张现代照片&#xff0c;展示了一座山峰和周围的自然景观&#xff0c;包括水体和植被。’] fro…

HTML和JavaScript实现商品购物系统

下面是一个更全面的商品购物系统示例&#xff0c;包含新增商品、商品的增加删除以及结算找零的功能。这个系统使用HTML和JavaScript实现。 1.功能说明&#xff1a; 这个应用程序使用纯HTML和JavaScript实现。 包含一个商品列表和一个购物车区域。商品列表中有几个示例商品&a…

Linux网络之“桥接模式”和“NAT模式”配置

介绍虚拟机的“桥接模式”和“NAT模式”配置。 1、“桥接模式”介绍 “桥接模式”将虚拟机的虚拟网络适配器与主机的“物理网络适配器”进行交接&#xff0c;虚拟机中的“虚拟网络适配器”通过主机中的“物理网络适配器”访问外部网络。物理主机的网卡好比是一个“虚拟的交换机…

Harmonyos之深浅模式适配

Harmonyos之换肤功能 概述实现原理颜色适配颜色资源配置工具类编写界面代码编写适配效果 概述 深色模式&#xff08;Dark Mode&#xff09;又称之为暗色模式&#xff0c;是与日常应用使用过程中的浅色模式&#xff08;Light Mode&#xff09;相对应的一种UI主题。 换肤功能应…

github配置pages并配置自定义域名

有cloudflare的话实现的效果更好&#xff0c;可以使用自己的域名&#xff0c;实现白嫖一个网站服务器 1、配置git&#xff08;可选步骤&#xff09; git init git config --global user.name "sijia" git config --global user.email "devopsgame.vip"g…