最全SpringCloud+Seata+nacos案例(包含源码 Seata及nacos安装教程),java面试技巧和注意事项

言尽于此,完结

无论是一个初级的 coder,高级的程序员,还是顶级的系统架构师,应该都有深刻的领会到设计模式的重要性。

  • 第一,设计模式能让专业人之间交流方便,如下:

程序员A:这里我用了XXX设计模式

程序员B:那我大致了解你程序的设计思路了

  • 第二,易维护

项目经理:今天客户有这样一个需求…

程序员:明白了,这里我使用了XXX设计模式,所以改起来很快

  • 第三,设计模式是编程经验的总结

程序员A:B,你怎么想到要这样去构建你的代码

程序员B:在我学习了XXX设计模式之后,好像自然而然就感觉这样写能避免一些问题

  • 第四,学习设计模式并不是必须的

程序员A:B,你这段代码使用的是XXX设计模式对吗?

程序员B:不好意思,我没有学习过设计模式,但是我的经验告诉我是这样写的

image

从设计思想解读开源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源码解读,我都已收集整理全套,篇幅有限,这块只是详细的解说了23种设计模式,整理的文件如下图一览无余!

image

搜集费时费力,能看到此处的都是真爱!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

enabled = false

registry-type = “compact”

multi exporters use comma divided

exporter-list = “prometheus”

exporter-prometheus-port = 9898

}

support {

spring

spring {

auto proxy the DataSource bean

datasource.autoproxy = false

}

}

b.registry.conf修改

registry {

file 、nacos 、eureka、redis、zk、consul、etcd3、sofa

type = “file”

nacos {

serverAddr = “localhost”

namespace = “”

cluster = “default”

}

eureka {

serviceUrl = “http://localhost:8761/eureka”

application = “default”

weight = “1”

}

redis {

serverAddr = “localhost:6379”

db = “0”

}

zk {

cluster = “default”

serverAddr = “127.0.0.1:2181”

session.timeout = 6000

connect.timeout = 2000

}

consul {

cluster = “default”

serverAddr = “127.0.0.1:8500”

}

etcd3 {

cluster = “default”

serverAddr = “http://localhost:2379”

}

sofa {

serverAddr = “127.0.0.1:9603”

application = “default”

region = “DEFAULT_ZONE”

datacenter = “DefaultDataCenter”

cluster = “default”

group = “SEATA_GROUP”

addressWaitTime = “3000”

}

file {

name = “file.conf”

}

}

config {

file、nacos 、apollo、zk、consul、etcd3

type = “file”

nacos {

serverAddr = “localhost”

namespace = “”

}

consul {

serverAddr = “127.0.0.1:8500”

}

apollo {

app.id = “seata-server”

apollo.meta = “http://192.168.1.204:8801”

}

zk {

serverAddr = “127.0.0.1:2181”

session.timeout = 6000

connect.timeout = 2000

}

etcd3 {

serverAddr = “http://localhost:2379”

}

file {

name = “file.conf”

}

}

3.创建seata数据库(mysql) 将seata->conf->db_store.sql放到数据库中运行即可

4.到bin目录下找到seata-server.bat运行即可 如下即为成功运行:

在这里插入图片描述

三.nacos安装


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

b.修改application.properties文件(将数据库对应配置注释打开即可)

在这里插入图片描述

c.找到startup.cmd编辑里面的将set MODE="cluster"一行改成set MODE=“standalone”

d.点击startup.cmd运行即可,如下即为成功:

在这里插入图片描述

e.访问localhost:8848即可 默认账号密码都是:nacos

四.项目案例


1.项目结构

在这里插入图片描述

account-service:负责对用户余扣减

business-service:负责完成下单的逻辑,包含 2 个主要的步骤,就是对库存服务和订单服务的远程调用

order-service:负责完成保存用户订单的操作

storage-service:负责完成对库存的扣减

2.各模块主要代码展示:

account-service

@Service

public class AccountServiceImpl implements AccountService {

@Autowired

private AccountTblMapper accountTblMapper ;

private static Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class) ;

@Transactional

@Override

public void debit(String userId, int money) {

logger.info(“开始扣减用户:{}的余额,数量为:{}”,userId ,money);

//1 查询数据库里面的账户

AccountTbl accountTbl = accountTblMapper.selectOne(new LambdaQueryWrapper().

eq(AccountTbl::getUserId, userId));

if(accountTbl==null){

throw new IllegalArgumentException(“此账号不存在”) ;

}

//2 扣减的操作

int idleMoney = accountTbl.getMoney() - money ;

// 3 库存的校验

if(idleMoney<0){

throw new RuntimeException(“库存不足”) ;

}

//4 设置到账户里面

accountTbl.setMoney(idleMoney);

//5 保存到数据库里里面

accountTblMapper.updateById(accountTbl) ;

if(“SXT_USER_2”.equals(userId)){

throw new RuntimeException(“不想成功”) ;

}

}

}

####Pom文件

com.baomidou

mybatis-plus-boot-starter

3.3.0

mysql

mysql-connector-java

business-service

@Service

public class BusinessServiceImpl implements BusinessService {

private static Logger logger = LoggerFactory.getLogger(BusinessServiceImpl.class) ;

@Autowired

private StorageServiceApi storageServiceApi ;

@Autowired

private OrderServiceApi orderServiceApi ;

@Override

public void purchase(String userId, String productNo, int count) {

logger.info(“准备下单,用户{},商品{},数量{}”,userId ,productNo ,count);

// 1 远程调用库存服务–> 库存的扣减f

storageServiceApi.deduct(productNo, count);

// 2 远程调用订单服务–>订单的新增

orderServiceApi.create(userId, productNo, count);

logger.info(“下单成功”);

}

}

####通过feign调用 代码:

OrderServiceApi

@Service

public class OrderServiceApi {

private static Logger logger = LoggerFactory.getLogger(OrderServiceApi.class) ;

// @Autowired

// private RestTemplate restTemplate ;

@Autowired

private OrderServiceFeign orderServiceFeign ;

public void create(String userId ,String productNo ,int count){

// ResponseEntity responseEntity = restTemplate.getForEntity(

// “http://order-service/create/{userId}/{productNo}/{count}”,

// Void.class,

// userId,

// productNo,

// count

// );

ResponseEntity responseEntity = orderServiceFeign.create(userId, productNo, count);

if(responseEntity.getStatusCode()== HttpStatus.OK){

logger.info(“远程调用订单服务成功”);

return;

}

throw new RuntimeException(“远程调用订单服务失败”) ;

}

}

StorageServiceApi

@Service

public class StorageServiceApi {

private static Logger logger = LoggerFactory.getLogger(StorageServiceApi.class) ;

// @Autowired

// private RestTemplate restTemplate ; //ribbon

@Autowired

private StorageServiceFeign storageServiceFeign ;

public void deduct(String productNo ,int count){

// ResponseEntity responseEntity = restTemplate.getForEntity(

// “http://storage-service/deduct/{productNo}/{count}”,

// Void.class,

// productNo,

// count

// );

ResponseEntity responseEntity = storageServiceFeign.deduct(productNo, count);

if(responseEntity.getStatusCode()== HttpStatus.OK){

logger.info(“远程调用库存服务成功”);

return;

}

throw new RuntimeException(“远程调用库存服务失败”);

}

}

###order-service

@Service

public class OrderServiceImpl implements OrderService {

@Autowired

private OrderTblMapper orderTblMapper ;

@Autowired

private AccountServiceApi accountServiceApi ;

private static Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class) ;

@Transactional

@Override

public OrderTbl createOrder(String userId, String productNo, int count) {

logger.info(“开始创建一个订单,用户为{},商品为{},数量为{}”,userId,productNo,count);

// 1 扣减用户的余额 account-service - >rpc

int money = cal(productNo,count) ;

ResponseEntity responseEntity = accountServiceApi.debit(userId, money);

if(responseEntity.getStatusCode()!= HttpStatus.OK){

throw new RuntimeException(“远程扣减用户的余额失败”) ;

}

//2 写本地的订单表

OrderTbl orderTbl = new OrderTbl();

orderTbl.setUserId(userId);

orderTbl.setCommodityCode(productNo);

orderTbl.setCount(count);

orderTblMapper.insert(orderTbl) ;

logger.info(“创建订单成功,用户为{},商品为{},数量{}”,userId,productNo,count);

return orderTbl;

}

/**

  • 计算商品的总价格

  • @param productNo

  • @param count

  • @return

*/

最后

2020年在匆匆忙忙慌慌乱乱中就这么度过了,我们迎来了新一年,互联网的发展如此之快,技术日新月异,更新迭代成为了这个时代的代名词,坚持下来的技术体系会越来越健壮,JVM作为如今是跳槽大厂必备的技能,如果你还没掌握,更别提之后更新的新技术了。

更多JVM面试整理:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

erTbl.setCount(count);

orderTblMapper.insert(orderTbl) ;

logger.info(“创建订单成功,用户为{},商品为{},数量{}”,userId,productNo,count);

return orderTbl;

}

/**

  • 计算商品的总价格

  • @param productNo

  • @param count

  • @return

*/

最后

2020年在匆匆忙忙慌慌乱乱中就这么度过了,我们迎来了新一年,互联网的发展如此之快,技术日新月异,更新迭代成为了这个时代的代名词,坚持下来的技术体系会越来越健壮,JVM作为如今是跳槽大厂必备的技能,如果你还没掌握,更别提之后更新的新技术了。

[外链图片转存中…(img-npcWc6Ql-1715583617892)]

更多JVM面试整理:

[外链图片转存中…(img-LnTK1wsj-1715583617892)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值