JSF十分钟入门指南

1. 新建接口

接入JSF之前需要新建接口,接口一般指的是java的interface,例如"com.jd.testjsf.HelloService"
如果已经在SAF中新建,则无需在JSF里新建接口。 

JSF注册中心和管理端地址参见:JSF线上环境和测试环境地址

测试环境:

可以在测试环境管理端“接口申请”菜单自行录入,无需审核。

线上环境

可以在线上环境管理端“接口申请”菜单自行录入,提交审核即可。

如果接口很多, 可以以附件形式导入 新建接口申请.xls 再提交

>>>小组联系人或者值班人员见 小组成员 

2.   DEMO下载  

快速简单Demo下载:   maven工程导入Eclipse或者Intellij IDEA即可。

单间Demo下载:

       点击下载:jsf-demo  

高级特性Demo下载: 

点击下载:jsf-example

3. JSF使用

3.1 建立工程、引入JSF

在pom里面引入jsf的jar包。

<dependency>

    <groupId>com.jd</groupId>

    <artifactId>jsf</artifactId>

    <version>最新版本</version>

</dependency>

如果需要发布Webservices,还得在项目中单独引入cxf的jar包。
如果需要发布Rest,还得在项目中单独引入resteasy相关的jar包 

3.2 发布服务

1. 新建服务接口类

HelloService

package com.jd.testjsf;

public interface HelloService {

    public String echoStr(String str);

}

2. 新建服务实现类

HelloServiceImpl

package com.jd.testjsf;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class HelloServiceImpl implements HelloService {

    private static Logger logger = LoggerFactory

            .getLogger(HelloServiceImpl.class);

    @Override

    public String echoStr(String str) {

        logger.info("server get request : {}", str);

        return str;

    }

}

3. 配置一下spring xml文件 (注意,文件头部要引入jsf.xsd相关配置

jsf-provider

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jsf="http://jsf.jd.com/schema/jsf"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

    http://jsf.jd.com/schema/jsf http://jsf.jd.com/schema/jsf/jsf.xsd">

    <!-- 实现类 -->

    <bean id="helloServiceImpl" class="com.jd.testjsf.HelloServiceImpl" />

    <!-- 注册中心   192.168.150.121 i.jsf.jd.com  #测试index服务地址 -->

    <jsf:registry id="jsfRegistry" protocol="jsfRegistry" index="i.jsf.jd.com" />

    <!-- 服务端 -->

    <jsf:server id="jsf" protocol="jsf"/>

    <!-- 发布服务 alias可以改成自己的 -->

    <jsf:provider id="helloService" interface="com.jd.testjsf.HelloService" alias="CHANGE-IT"

                 ref="helloServiceImpl" server="jsf" >

    </jsf:provider>

</beans>

4. 启动服务

ServerMain

package com.jd.testjsf;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ServerMain {

    private final static Logger LOGGER = LoggerFactory.getLogger(ServerMain.class);

    public static void main(String[] args) {

        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("/jsf-provider.xml");

        LOGGER.info("服务端启动完成!");

         

        // 启动本地服务,然后hold住本地服务

        synchronized (ServerMain.class) {

            while (true) {

                try {

                    ServerMain.class.wait();

                } catch (InterruptedException e) {

                }

            }

        }

    }

}

5. 去注册中心管理端查看是否启动成功。

管理端登陆后,左侧点击服务管理-服务管理菜单,右侧搜索刚发布的“com.jd.testjsf.HelloService”接口(如果没搜到上面展示类型选所有)

可以看到刚刚启动的一个Provider信息。

恭喜你,你已经成功了一半!!!

3.3 调用服务

1. 引入接口类:

一般为服务发布者将接口打成jar包,上传到公司的maven私服给服务调用者。
或者直接将接口类告诉服务调用者。

请注意:服务匹配是依靠 interface(接口) 以及 alias(别名)两个配置来完成的;

也就是说调用端(Service Consumer)必须与服务端(Service Provider)的interface 与alias 属性配置必须完全一致,否则调用时会收到一个No Provider(没有服务提供者)的错误!

2. 配置一下spring xml文件

jsf-consumer.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jsf="http://jsf.jd.com/schema/jsf"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

    http://jsf.jd.com/schema/jsf http://jsf.jd.com/schema/jsf/jsf.xsd">

    <!-- 注册中心  192.168.150.121 i.jsf.jd.com  #测试index服务地址 -->

    <jsf:registry id="jsfRegistry" protocol="jsfRegistry" index="i.jsf.jd.com"/>

    <!-- 服务调用者配置 直连使用 url="jsf://10.12.113.111:22000;jsf://10.12.113.112:22000" -->

    <jsf:consumer id="helloService" interface="com.jd.testjsf.HelloService"

                   protocol="jsf" alias="CHANGE-IT" timeout="10000" >

    </jsf:consumer>

</beans>

3. 注入到代码中进行调用

可以通过applicationContext.getBean(name)获取,也可以使用spring的getter/setter注入,也可以使用@AutoWired或者@Resource注入。

下面的例子是通过getBean注入的。

ClientMain

package com.jd.testjsf;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ClientMain {

    private final static Logger LOGGER = LoggerFactory.getLogger(ClientMain.class);

    public static void main(String[] args) {

        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("/jsf-consumer.xml");

        HelloService service = (HelloService) appContext.getBean("helloService");

        LOGGER.info("得到调用端代理:{}", service);

        while (true) {

            try {

                String result = service.echoStr("zhanggeng put");

                LOGGER.info("response msg from server :{}", result);

            } catch (Exception e) {

                LOGGER.error(e.getMessage(), e);

            }

            try {

                Thread.sleep(2000);

            } catch (Exception e) {

            }

        }

        // JSFContext.destroy();

    }

4. 可以在Console里看到调用日志,

服务端

客户端:

当然在管理端我们也能看到调用者信息

管理端登陆后,左侧点击服务管理-服务管理菜单,右侧搜索刚发布的“com.jd.testjsf.HelloService”接口(如果没搜到上面展示类型选所有)

再次恭喜,你已经完成了JSF的发布和调用!!

更多高级功能,请参见下面的最佳实践和参考手册。

4. 最佳实践

4.1 关于接口设计

1.目前jsf未支持分布式事务,所以接口的设计一般要保证事务完整性。

2.写入的服务最好是幂等服务,如果不幂等要求有排重处理。

3.同一接口同一alias下的全部实例应该是对等的,即随便调到那一台效果是一样的;
   如果一个接口要按业务区分的,则要求使用不同服务别名alias或者拆为两个接口。

4.方法上面要求显式的抛出可能出现的异常,即使是自定义的一些runtime异常
(针对com.jd.jsf.gd.error.RpcException等JSF的异常,可能引起特殊处理例如重试,尽量不要使用)。

5.方法名要求含义明确且唯一,不要使用重载方法(即同样方法名不同参数个数)。

6.自定义对象最好实现java.io.Serializable,对象中不传递的值增加transient关键字。

7.自定义对象数据结构要求尽量简洁,尽量不要多层循环嵌套。增加字段注意保证原有顺序,在最后加新的字段

8.避免接口参数使用父类,调用时传入子类的设计。 

4.2 关于发布

1.如想配置Provider使用随机端口,请将port的值置为-1,其实还是从指定端口往上轮。
   <jsf:server id="myjsf" protocol="jsf" port="-1" /> 

2.服务器多网卡多IP时,会随机取连上注册中心的地址,为了解决这个问题,可在<jsf:server>中设置host,配置如下:
   <jsf:server id="myjsf" protocol="jsf" host="10.12.113.111" />。

3.开发环境和测试环境使用不同的group/alias,防止调用错了。

虚拟机部署问题:

1.虚拟机由于资源有限,可缩小线程池最大线程数,默认初始化20最大为200,参考配置 <jsf:server threads="20" />。

2.配置每线程所使用栈内存大小,设置JVM参数 -Xss=256K,并查看ulimt -u ulimit -s确认是否满足需求。

4.3 关于调用

1.调用读服务最好使用重试,增强客户体验;
   写服务不要依赖jsf重试,防止数据重复,<jsf:consumer retries="0" />

2.开发环境自己测试可以使用直连,防止调用到别的机器。
   <jsf:consumer url="jsf://127.0.0.1:20880;……" />

3.在JSF调用链中(例如A调B,B里面调C),外层调用的超时时间要求大于内层调用的超时时间(即A调B的超时时间要大于B调C的超时时间)

5. 参考手册

配置说明 JSF配置参考手册

功能特性 JSF用户手册

更多问题参考 JSF FAQ

入门视频 JSF入门视频   

猜你喜欢

转载自blog.csdn.net/u010029064/article/details/81355741