黑马商城学习项目02-微服务拆分
黑马商城学习项目 02 - 微服务拆分
1. 熟悉黑马商城:先逛明白超市再开分店
想象黑马商城是家网红超市,刚开业时所有货架、收银台、仓库挤在一个大仓库里(单体架构)。咱们得先摸清楚各区域的位置和运作逻辑,不然以后拆分店(微服务)会乱成一锅粥。
启动前的 “密码破译”
启动项目前得改数据库配置,这就像超市开业前要拿到仓库钥匙:
1 | hm: |
还要在启动项里选 “local 环境”,相当于告诉系统:”我用自己的钥匙开门,不用备用钥匙”。
各功能区深度探秘
- 登录系统:在
UserController的login方法里。就像超市的会员系统,你得刷脸(输入账号密码)才能解锁会员福利,后台会生成一个 “临时通行证”(token),拿着它才能逛付费区。 - 商品搜索:首页搜索框对应
SearchController的search方法。比如你搜 “螺蛳粉”,系统会在商品库里翻箱倒柜(数据库分页查询),把所有螺蛳粉摆到你面前,还贴心地分了页(怕你看不过来)。 - 购物车操作:
CartController管着所有 “装货、卸货、改数量” 的操作。就像你拿个购物篮,选了东西放进去(添加)、不想要了拿出来(删除)、觉得不够再拿一包(修改数量)。 - 下单流程:
OrderController的createOrder是核心。点击 “结算” 的瞬间,系统会干三件事:给你开一张购物小票(创建订单)、从仓库扣掉相应货物(减库存)、清空你的购物篮(清空购物车)。 - 支付环节:
PayController负责收钱。选 “余额支付” 后,系统先开个 “收款单”(支付流水),等你输完密码,就会扣掉余额、改收款单状态(已支付)、再把购物小票标成 “已付款”。
2. 服务拆分原则:分家得有章法
什么时候该分家?
- 小项目初期:就像小夫妻刚结婚,住一居室(单体架构)足够了。省房租(开发成本)、收拾起来方便(维护简单),先试试日子能不能过下去(验证市场)。等生了娃(用户变多)、换了大 house(业务复杂),再考虑分房间(拆微服务)。
- 大型项目开局:好比一开始就买了别墅(微服务架构),客厅、卧室、厨房早规划好。虽然装修费贵(前期投入大),但后期家人多了也不挤(可扩展性强),不用费劲改格局(避免后期拆分麻烦)。
怎么分才不打架?
- 高内聚:一个服务只干一类事,就像厨房只做饭、卧室只睡觉。商品服务就管商品的增删改查、库存变动;订单服务就管订单创建、状态修改。不能让商品服务去操心订单怎么付款,不然就像让厨房兼做卧室,乱套!
- 低耦合:服务之间少串门,非要交流就得有规矩。比如订单服务需要商品价格,不能直接闯进商品服务的仓库(查数据库),得按门铃(调用接口):”您好,麻烦告诉我这个商品的价格 ~”。商品服务也得守规矩,只要接口没变,内部怎么折腾(改代码)都不影响外面。
举个生动例子:
- 纵向拆分:把超市分成 “生鲜区”(商品服务)、”收银台”(支付服务)、”储物柜”(购物车服务)。每个区域独立运营,各管一摊事。
- 横向拆分:发现每个区域都需要 “打包袋”(发送消息),那就单独设个 “打包袋供应处”(消息服务),谁需要谁来领,不用每个区域自己生产袋子,省事儿!
3. 拆分购物车、商品服务:搬家打包指南
商品服务(item-service):给商品找个独立仓库
第一步:搭个新仓库(创建模块)
在父工程里建个叫 item-service 的模块,就像在超市旁边盖了个专门放零食的仓库。pom.xml 里得配齐家当(依赖):web 模块(接待客人)、数据库连接(开门钥匙)、mybatis(记账本),少一样都运转不起来。
第二步:写个仓库招牌(启动类)
1 | // 告诉系统账本在哪 |
这就像在仓库门口挂个牌子:”商品仓库,正常营业”。
第三步:规划仓库布局(配置文件)
- 端口设为 8081:相当于仓库门牌号,别人找得到
- 数据库改名为
hm-item:专门放商品的账本,和其他账本分开 - 其他配置照搬但微调:就像仓库的规章制度,大体和总超市一样,但细节有自己的特色
第四步:搬东西(拷贝代码)
把原来单体项目里和商品相关的 Controller、Service、Mapper 都挪过来。注意!ItemServiceImpl 里有个 deductStock 方法,原来的 ItemMapper 地址变了,得重新指路(改包路径),不然系统会找不到账本。
第五步:录入账本(导入数据库)
执行 SQL 文件创建 hm-item 数据库,里面放着商品的所有信息(库存、价格、名称)。就像给新仓库建立单独的库存表,以后商品进出都在这记账。
验收:仓库试营业
启动服务后访问 http://localhost:8081/doc.html,用 swagger 测试 “批量查商品” 接口。输入几个商品 ID,能返回价格、库存,说明仓库运转正常,就像顾客问 “有没有可乐”,仓库能准确报出 “有,3 块钱一瓶,剩 100 瓶”。
购物车服务(cart-service):给购物篮建个管理处
流程和商品服务类似,但有两个小坑要填:
坑 1:暂时不知道用户是谁
原来的登录功能还在老超市(单体项目),购物车服务暂时认不出谁在操作,只能先写死一个用户 ID(比如 1L),就像暂时用 “临时访客” 身份记录购物篮。
坑 2:查不到商品价格
购物车需要显示商品价格,但商品已经搬到新仓库了。原来直接喊一声(本地调用)就能问到,现在得跨仓库沟通。暂时先把这部分代码注释掉,就像购物篮暂时只记 “买了啥”,不记 “多少钱”,等后面装了电话(服务调用)再补上。
4. 服务调用:给两个仓库装部电话
拆分后,购物车想知道商品价格,总不能让员工跑过去问吧?得装部电话(远程调用)。
RestTemplate:这电话很好用
在购物车服务里注册一个 RestTemplate,相当于装了部电话机:
1 |
|
打电话查价格:标准流程
修改 CartServiceImpl 的 handleCartItems 方法,让购物车服务主动打电话问商品服务:
1 | // 1. 先记下来要问哪些商品(收集商品ID) |
现在重启购物车服务,再查购物车,商品价格就出来了,就像购物篮上终于贴了价签。这时候,商品服务是 “被咨询的仓库”(服务提供者),购物车服务是 “打电话的咨询者”(服务消费者)。
5. 总结:拆家是为了更好地过日子
- 拆分时机:小项目先凑活住(单体),人多了再分房(微服务);大项目一开始就规划好房间(微服务),免得后期拆墙(重构)。
- 拆分技巧:每个服务专注一件事(高内聚),服务间少串门(低耦合),交流靠规矩(接口)。
- 远程调用:就像跨部门沟通,用
RestTemplate这部电话,按规矩拨号(HTTP 请求),就能问到想要的信息。
记住:微服务拆分不是为了炫技,而是为了让系统像乐高积木,哪个零件坏了换哪个,想加新功能直接加块积木,不用把整个玩具拆了重拼 ~
-
感谢你赐予我前进的力量