1.什么是SOA架构

SOA是Service-Oriented Architecture的首字母简称,它是一种支持面向服务的架构样式。从服务、基于服务开发和服务的结果来看,面向服务是一种思考方式。其实SOA架构更多应用于互联网项目开发。

为什么互联网项目会采用SOA架构呢?随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,迫切需一个治理系统确保架构有条不紊的演进。

这个项目用的dubbox就是SOA解决方案的一种

2.品优购架构图

soa java 架构 soa架构搭建_soa java 架构

3.框架组合

品优购采用当前流行的前后端编程架构。

后端框架采用Spring +SpringMVC+mybatis +Dubbox 。前端采用angularJS + Bootstrap。

4.Dubbox

Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继续维护,为了与原有的Dubbo区分,故将其命名为Dubbox。

Dubbox 致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbox就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbox这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。

soa java 架构 soa架构搭建_Dubbox及小demo_02

节点角色说明:
· Provider: 暴露服务的服务提供方。
· Consumer: 调用远程服务的服务消费方。
· Registry: 服务注册与发现的注册中心。
· Monitor: 统计服务的调用次调和调用时间的监控中心。
· Container: 服务运行容器。
调用关系说明:
· 0. 服务容器负责启动,加载,运行服务提供者。
· 1. 服务提供者在启动时,向注册中心注册自己提供的服务。
· 2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
· 3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推
送变更数据给消费者。
· 4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,
如果调用失败,再选另一台调用。
· 5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计
数据到监控中心。
5.注册中心Zookeeper
官方推荐使用 zookeeper 注册中心。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbox 服务的注册中心,工业强度较高,可用于生产环境。
6.注册中心安装到linux环境并启动
1.打开VMWARE,将双击后缀为vmx的镜像文件(镜像中JDK装好了,并且dubbox的jar也部署安装了)
2.在VMWARE中把网络适配器改为仅主机模式,把子网IP改为25网段,后面要连FASTDNS,也是25网段
3.打开虚拟机,登陆账户名 root 密码 itcast
打开终端,输入ipconfig查看服务器ip,这里为192.168.25.131
4.工作中是需要客户端连接linux服务器的,打开CRT(还可以用XSHELL等)
new session 输入IP用户名密码进行连接

soa java 架构 soa架构搭建_Zookeeper_03

5.Alt+P 进入SFTP ,输入put d:\setup\zookeeper-3.4.6.tar.gz 上传(或者直接拖上来)
6.tar -zxvf zookeeper-3.4.6.tar.gz 解压
7.在zookeeper文件夹下创建data文件夹
mkdir data
8.进入conf目录 ,把 zoo_sample.cfg 改名为 zoo.cfg
cd conf
mv zoo_sample.cfg zoo.cfg
9.然后修改配置
vim zoo.cfg --打开配置文件
点击 i 进入插入模式
将dataDir配置的路径改为我们创建的data文件夹的路径
dataDir=root/zookeeper-3.4.6/data
然后点Esc退出,输入 :wq 进行保存
10.启动zookeeper服务
./zkServer.sh start 进行启动  
./zkServer.sh stop 停止 
./zkServer.sh status 查看状态

7.dubboxjar包安装与部署(用的镜像所以这个步骤不需要)

先将dubbo-2.8.4.jar包放到d:\setup, 然后输入命令

mvn install:install-file -Dfile=d:\setup\dubbo-2.8.4.jar -DgroupId=com.alibaba -DartifactId=dubbo -Dversion=2.8.4 -Dpackaging=jar

8.配置dubbox约束 

soa java 架构 soa架构搭建_SOA架构_04

9.dubbox小demo编写

(1).服务端
1.创建maven工程,war,把pom.xml内容考进来,修改端口号为8081
2.发现报错,新建WEB-INF文件夹,把web.xml考进来
3.代码
新建接口
package com.itheima.demo.service;
public interface UserService {
     public String getName();
 }新建实现类(注意Service导的是dubbo的包,代表是个对外发布的服务)
package com.itheima.demo.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
 import com.itheima.demo.service.UserService;@Service
 public class UserServiceImpl implements UserService {    @Override
     public String getName() {
         // TODO Auto-generated method stub
         return "juejue";
     }}
 4.把applicationContext-service.xml考到resources下,注意命名与xml中加载的形式相符加入如下配置,应用名称是项目名,注册中心地址是我们ifconfig查的ip,服务地址是接口所在包名
<!-- 引用dubbo 服务 -->
        <!-- 当前应用名称,表明是一个服务 -->
     <dubbo:application name="dubboxdemo-service" />
     <!-- 注册中心地址 -->
     <dubbo:registry address = "zookeeper://192.168.25.131:2181"/>
     <!-- 包扫描,扫描服务提供的地址 -->
        <dubbo:annotation package = "com.itheima.demo.service"/>5.运行服务
右键项目 --》run as --》maven build... -->Goals里输入 tomcat7:run(报错可能是因为注册中心zookeeper没启动)
(2)调用端
1.创建maven工程,war,把pom.xml内容考进来,修改端口号为8082
2.发现报错,新建WEB-INF文件夹,把web.xml考进来
3.把服务端的service接口包拷过来,然后新增controller层,这里要使用reference标签

soa java 架构 soa架构搭建_Zookeeper_05

4.    <!-- 当前应用名称 -->
springMvc.xml中配置如下
     <dubbo:application name="dubboxdemo-web" />
     <!-- 注册中心地址 -->
     <dubbo:registry address="zookeeper://192.168.25.130:2181"/>
     <!-- 包扫描,扫描服务消费方的地址 -->
      <dubbo:annotation package="com.itheima.demo.controller" />5.运行服务
右键项目 --》run as --》maven build... -->Goals里输入 tomcat7:run
效果如下,说明成功调用服务

soa java 架构 soa架构搭建_SOA架构_06

10.管理中心项目部署到linux服务器上
有个界面方便对服务的查看,两种方式,在配套软件的懒人资源里找到
2.找到dubbo-admin所在路径,打成war包,这样就可以在target文件夹中找到

soa java 架构 soa架构搭建_项目打包_07

soa java 架构 soa架构搭建_SOA架构_08

把版本去掉,改名为dubbo-admin.war(改了方便点)
3.然后上传到linux服务器上
alt+p  切换为文件上传模式 --> put  D:\setUp\dubbo-admin.war 上传到根目录 -->
4.部署
put  D:\setUp\apache-tomcat-7.0.52.tar.gz 把tomcat也传上来 --》将tomcat解压 tar -zxvf  apache-tomcat-7.0.52.tar.gz --》mv  dubbo-admin.war  apache-tomcat-7.0.52/webapps 将管理中心项目的war包放在tomcat的webapps下  就部署好了!
5.访问管理中心

soa java 架构 soa架构搭建_项目打包_09

然后就可以查看服务,服务的提供者与消费者等信息了

soa java 架构 soa架构搭建_项目打包_10

10.工程结构分析与设计

最终完整的工程结构如下:既按层分也按业务分

soa java 架构 soa架构搭建_SOA架构_11

shop-web:商家管理后台,manager-web:运营商管理后台
工程说明:
pinyougou-common  把所有工程都要用到的东西都放到common里,比如工具类
pinyougou-parent 聚合工程 定义所有要用到jar的版本
pinyougou-pojo 通用实体类层
pinyougou-dao 通用数据访问层
pinyougou-xxxxx-interface  某服务层接口  web与service都会引用interface,就不用像demo那样写两次接口类了
pinyougou-xxxxx-service   某服务层实现
pinyougou-xxxxx-web     某web工程  
11.创建数据库表
执行资源文件夹中pinyougou-db.sql

12.搭建框架

创建父工程,pinyougou-parent pom工程,在第一天搭建中拷贝pom.xml,定义相关依赖的版本号
下面创建工程时父工程都选择pinyougou-parent
新建maven module pinyougou-pojo  jar工程
新建maven module pinyougou-dao  jar工程
新建maven module pinyougou-dao  jar工程
新建maven module pinyougou-common jar工程
新建maven module pinyougou-sellergoods-interface jar工程   //商家商品接口
新建maven module pinyougou-sellergoods-service war工程  //服务,要部署到tomcat所以war
新建maven module pinyougou-manager-web war工程   //运营商管理后台
新建maven module pinyougou-shop-web war工程   //商家管理后台
 将配置文件都拷进去,然后添加模块间的依赖
dao依赖pojo,service依赖dao,web与service都依赖interface,interface依赖pojo
如果分了几个版本找不到当前版本就maven reposoitories下重建下索引,然后不同service与web端口
统一配置9001 9101 9002 9102这样,方便记
同时跑很多服务时要加上这一行,不同服务配不同端口

soa java 架构 soa架构搭建_项目打包_12

运行子模块时如果报缺少依赖的错,先把父项目install下

13.逆向工程实体类与数据访问层  //记得改数据库名与密码

soa java 架构 soa架构搭建_Zookeeper_13

soa java 架构 soa架构搭建_Dubbox及小demo_14

把生成的文件考到对应项目的resources文件夹下,
实体类除example类都要实现serializable可序列化接口,因为要在网络上传输

14.后端代码  //使用rest'Cont'ro'ller注解就相当于controller+responsebody

(1)服务层接口

在pinyougou-sellergoods-interface 工程创建BrandService接口
package com.pinyougou.sellergoods.service;
import java.util.List;
import com.pinyougou.pojo.TbBrand;
/**
 * 品牌服务层接口
 * @author Administrator
 *
 */
public interface BrandService {
/**
 * 返回全部列表
 * @return
 */
public List<TbBrand> findAll();
}

(2) 服务实现类

在pinyougou-sellergoods-service 工程创建BrandServiceImpl类
package com.pinyougou.sellergoods.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
@Service
public class BrandServiceImpl implements BrandService {
@Autowired
private TbBrandMapper brandMapper;
@Override
public List<TbBrand> findAll() {
return brandMapper.selectByExample(null);
}
}
(3) 控制层代码
在pinyougou-manager-web工程创建com.pinyougou.manager.controller包,包下创建BrandController类
package com.pinyougou.manager.controller;
import java.util.List;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
/**
 * 品牌controller
 * @author Administrator
 */
@RestController
@RequestMapping("/brand")
public class BrandController {
@Reference
private BrandService brandService;
/**
 * 返回全部列表
 * @return
 */
@RequestMapping("/findAll")
public List<TbBrand> findAll(){
return brandService.findAll();
}
}
(4)测试
启动pinyougou-sellergoods-service  
启动pinyougou-manager-web 
地址栏输入http://localhost:9101/brand/findAll.do
可以看到浏览器输出了json数据。
15.常见错误
(1).在注册中心找不到对应的服务
java.lang.IllegalStateException: Failed to check the status of the service com.pinyougou.sellergoods.service.BrandService. No provider available for the service com.pinyougou.sellergoods.service.BrandService from the url zookeeper://192.168.25.129:2181/com.alibaba.dubbo.registry.RegistryService?applicatinotallow=pinyougou-manager-web&dubbo=2.8.4&interface=com.pinyougou.sellergoods.service.BrandService&methods=update,get,delete,selectOptionList,add,getListByPage&pid=3980&revisinotallow=0.0.1-SNAPSHOT&side=consumer×tamp=1501146823396 to the consumer 172.16.17.14 use dubbo version 2.8.4
这种错误是服务层代码没有成功注册到注册中心导致,请检查一下你的服务层代码是否添加了@service注解,并且该注解的包一定是com.alibaba.dubbo.config.annotation包,不是org.springframework.stereotype.Service,这个地方极容易出错。另外还有一个原因就是你的服务层工程由于某些原因没有正常启动,也无法注册到注册中心里,还有扫描包跟自己定义
的包格式要匹配
(2).无法连接到注册中心  
org.I0Itec.zkclient.exception.ZkTimeoutException: Unable to connect to zookeeper server within timeout: 5000 org.I0Itec.zkclient.ZkClient.connect(ZkClient.java:876) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:98) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:92) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:80)
com.alibaba.dubbo.remoting.zookeeper.zkclient.ZkclientZookeeperClient.<init>(ZkclientZookeeperClient.java:26)
请检查IP与端口是否填写正确,检查注册中心是否正常启动