参考:https://www.jianshu.com/p/4a9b7680b47b
参考:https://www.cnblogs.com/gzyy1987/p/4703478.html
定义一个注解类,方便使用注解的方式自动注入服务类。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RemoteService {
String value() default "" ;
}
定义数据交互的端口直接在构造函数中传入端口就可以了。这样方式最为简单。@RemoteService为自定义的注解值,方便使用注解的方式定义服务。注意实现类要继承自UnicastRemoteObject类。可以设置一个类继承自UnicastRemoteObject类,并在这个类中实现数据端口的定义【super(10087)】。
@Service
@RemoteService
public class CityServiceImple extends UnicastRemoteObject implements CityService {
private static final long serialVersionUID = 1L;
@Autowired
private CityDao cityDao;
@Autowired
private DataSourceHelper dataSourceHelper;
@Autowired
private DataInfoService dataInfoService;
public CityServiceImple() throws Exception {
super(10087);
}
@Override
public City selectByPrimaryKey(Integer companyid,Long cityid) throws RemoteException {
String key = dataInfoService.getDataSourceKey(companyid, DataSourceEnum.Comm.name(), OperationType.Read);
DynamicDataSource.setDataSourceKey(dataSourceHelper.getDataSourceKey(key));
return cityDao.selectByPrimaryKey(cityid);
}
@Override
public List<City> getAll(Integer companyid) throws RemoteException {
String key = dataInfoService.getDataSourceKey(companyid, DataSourceEnum.Comm.name(), OperationType.Read);
DynamicDataSource.setDataSourceKey(dataSourceHelper.getDataSourceKey(key));
return cityDao.getAll();
}
}
注意服务类要实现 继承Remote。
public interface CityService extends Remote{
City selectByPrimaryKey(Integer companyid,Long cityid) throws java.rmi.RemoteException;
List<City> getAll(Integer companyid) throws java.rmi.RemoteException;
}
下面是启动服务的源码
public static void main(String[] args) {
logger.debug("RMI服务端启动......");
System.out.println("RMI服务端启动");
try {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
int port = Integer.parseInt(PropertyUtils.getValue("rmi.port"));
Registry registry = LocateRegistry.createRegistry(port);
String rmiIP=PropertyUtils.getValue("rmi.ip");
System.setProperty("java.rmi.server.hostname",rmiIP);
// 在端口上创建一个远程对象注册表
/*try{
registry = LocateRegistry.getRegistry(port);
}catch(RemoteException e){
System.out.println("RMI服务不存在");
registry = LocateRegistry.createRegistry(port);
logger.debug("RMI服务不存在");
}*/
Map<String, Object> beans = ctx.getBeansWithAnnotation(RemoteService.class);
for (Entry<String, Object> item : beans.entrySet()) {
String name =
(AopUtils.getTargetClass(item.getValue()).getInterfaces()[0]).getName();
String bindstr = String.format("rmi://%s:%d/%s", rmiIP,port, name);
System.out.println(bindstr);
//registry.rebind(bindstr, (Remote) item.getValue());
Naming.bind(bindstr, (Remote) item.getValue());
}
System.out.println("RMI服务端启动完成");
Scanner sc = new Scanner(System.in);
while (true) {
String o = sc.nextLine();
if (o.equals("shutdown")) {
UnicastRemoteObject.unexportObject(registry, true);
System.out.println("RMI服务关闭");
break;
}
if (o.equals("start")) {
registry = BindRMI(port, ctx);
}
}
sc.close();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
下面是直接启动jar文件的shell
#!/bin/bash
#description: 启动重启server服务
#端口号,根据此端口号确定PID
#******************************************需要配置*************************************************************************#
PORT=10086
#启动命令所在目录
#******************************************需要配置*************************************************************************#
HOME='/usr/local/src'
#查询出监听了PORT端口TCP协议的程序
pid=`netstat -anp|grep $PORT|awk '{printf $7}'|cut -d/ -f1`
start(){
if [ -n "$pid" ]; then
echo "server already start,pid:$pid"
return 0
fi
#进入命令所在目录
#******************************************需要配置*************************************************************************#
cd $HOME
#nohup java -jar $HOME/RMIService.jar > /logs/rmiervice.log 2>&1 & #启动聊天服务器 把日志输出到HOME目录的server.log文件中
nohup java com.acexe.service.RMIService > /u01/logs/rmiervice.log 2>&1 & #直接使用classs启动
echo "start at port:$PORT"
}
stop(){
if [ -z "$pid" ]; then
echo "not find program on port:$PORT"
return 0
fi
#结束程序,使用讯号2,如果不行可以尝试讯号9强制结束
kill -9 $pid
rm -rf $pid
echo "kill program use signal 2,pid:$pid"
}
status(){
if [ -z "$pid" ]; then
echo "not find program on port:$PORT"
else
echo "program is running,pid:$pid"
fi
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
$0 stop
sleep 2
$0 start
;;
status)
status
;;
*)
echo "Usage: {start|stop|status}"
;;
esac
exit 0
自启动使用supervisor就可以了。只需要在ini文件中配置command时增加 start参数即可。参考:https://mp.csdn.net/postedit/84630869
[program:rmiservice]
directory=/usr/local/src/
;command=/usr/local/src/rmiservice.sh start run
command=java -jar /usr/local/src/tools/websocketServer.jar > /u01/logs/websocketServer.log 2>&1 &
environment=JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64",JAVA_BIN="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/bin"
user=root
autostart=true
autorestart=true
startsecs=10
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log